如何使用自定义布局跳转到UICollectionView中的任何单元格?

时间:2015-07-21 18:37:31

标签: ios swift uicollectionview

我的水平UICollectionView和一个按钮中有40个单元格。

当我点击按钮时,我可以从5号单元格跳转到10号单元格。

但是一旦我想要进一步的细胞(例如从5到25),

它不起作用,而是转到0。

代码:

func setValue(value: Int, animated: Bool) {
   self.value = value
   if let row = find(values, value) {
   let indexPath = NSIndexPath(forRow: row, inSection: 0)
   selectedCell = collectionView.cellForItemAtIndexPath(indexPath) as? StepperCell
   collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .CenteredHorizontally, animated: animated)
  }
 }

override func prepareLayout() {
   let start = Int(collectionView!.bounds.size.width * 0.5) - statics.width / 2
   let length = collectionView!.numberOfItemsInSection(0)

if cache.isEmpty && length > 0 {
   for item in 0..<length {
     let indexPath = NSIndexPath(forItem: item, inSection: 0)
     let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
     attributes.frame = CGRect(
      x: start + (statics.width + statics.padding) * indexPath.item,
      y: 0,
      width: statics.width,
      height: statics.height
    )
    cache.append(attributes)
  }
  contentWidth = CGRectGetMaxX(cache.last!.frame) + CGFloat(start)
   }
 }

 override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
   var layoutAttributes = [UICollectionViewLayoutAttributes]()
   for attributes in cache {
      if CGRectIntersectsRect(attributes.frame, rect) {
        layoutAttributes.append(attributes)
    }
  }
  return layoutAttributes
  }
 }

enter image description here

2 个答案:

答案 0 :(得分:5)

我认为你可以省去行逻辑。毕竟 - 你只是使用传递的Int。如果您的if let子句失败,则无法滚动。

此外,将电话放到cellForItemAtIndexPath - 您不需要它(您也没有使用它)。

我想也许你应该使用NSIndexPath(forItem, inSection)而不是NSIndexPath(forRow, inSection)。 (表视图使用,collectionView使用。)

collectionView.scrollToItemAtIndexPath(
      NSIndexPath(forItem: value, inSection: 0), 
      atScrollPosition: .CenteredHorizontally, animated: true)

答案 1 :(得分:1)

经过一些研究,以及来自编码员的一些帮助。我想出了一个更简单,更有效的解决方案。 我只使用自定义布局来捕捉效果(当在单元格之间切换时),然后我让流程布局处理其余部分。 这是代码:

MethodThatTakesListOfInt(
    myFoobars
        .Select(f => f.TheNumber)
        .ToList());

SomeMethodThatReturnsListOfString()
    .Select((s,i) => new { Index = i, String = s })
    .ToList()
    .ForEach(x => myFoobars[x.Index].TheString = x.String);