Select 默认在 collectionView 中滚动的单元格

Select cell on scroll in collectionView by default

我有一个自定义的集合视图布局,它似乎产生了一些错误。或者也许我错过了什么。布局看起来像这样,它来自 here

我的问题是我无法将居中单元格的 indexPath 传递给粉红色按钮,centerCellIndexPath 的调用产生 nil。我还尝试在布局本身中预先 select 单元格,如下所示:

 override open func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    // item's setup ......
    // ...................

    let finalPoint = CGPoint(x: newOffsetX, y: proposedContentOffset.y)

    // Select cell in collectionView by Default
    let updatePoint = CGPoint(x: newOffsetX, y: 180)
    let indexPath = collectionView!.indexPathForItem(at: updatePoint)
    self.collectionView!.selectItem(at: indexPath, animated: false, scrollPosition: [])

    return finalPoint
}

但是没用。我必须通过向上滑动来手动 select 单元格,这对用户来说非常不清楚。我应该如何在不点击和滑动的情况下 select 单元格?

如有任何建议,我们将不胜感激

UPD:多亏了 Vollan

,经过一夜无眠终于搞定了
func scrollViewDidScroll(_ scrollView: UIScrollView) {

    let position = 2 * scrollView.contentOffset.x / collectionView.superview!.frame.width

    selectedItem = Int(round(position))


}

UPD:但是最好的变得更好了。将链接的答案转换为 Swift 版本

This would be better code because it's cleaner and easier to read, all the content offset calculation is superfluous:

 NSIndexPath *centerCellIndexPath = 
[self.collectionView indexPathForItemAtPoint:
[self.view convertPoint:[self.view center] toView:self.collectionView]];

This would also be the correct representation of what you're actually trying to do: 1. Taking the center point of your viewcontroller's view - aka visual center point 2. convert it to the coordinate space of the view you're interested in - which is the collection view 3. Get the indexpath that exist at the location given.

所以需要 2 行:

 let centerPoint = self.view.convert(view.center, to: collectionView)
 let indexPath = collectionView.indexPathForItem(at: centerPoint)
 -> save media[indexPath.row]

这基本上就是 Sachin Kishore 的建议,但起初我不理解他

我有点喜欢动态 indexPath 的想法,但它需要一些舍入,这是不可靠的。所以我觉得convertindexPathForItem这里最好

func viewIndexPathInCollectionView(_ cellItem: UIView, collView: UICollectionView) -> IndexPath? {
    let pointInTable: CGPoint = cellItem.convert(cellItem.bounds.origin, to: collView)
    if let cellIndexPath = collView.indexPathForItem(at: pointInTable){
        return cellIndexPath
    }
    return nil

}

在按钮操作上调用此函数并在此函数上传递按钮名称、集合视图名称

如果您要将逻辑放入 scrollViewDidScroll,您可以动态更新 indexPath

let position = scrollView.contentOffset.x/(cellSize+spacing)
currenIndexPath.item = position

这应该始终为您提供当前单元格的索引路径。