在 UICollectionView 中查找每行实际显示的项目数

Find the actual displayed number of items per row in a UICollectionView

我有一个 UICollectionView 的矩形单元格,其大小基本一致,并带有库存 UICollectionViewFlowLayout

我正在尝试在应用程序的 Catalyst 版本中实现键盘箭头导航。左右都没有问题。这是一个完整的示例:

@objc func myRightKey() {
    var curr = glyphCollectionOutlet.indexPathsForSelectedItems?.first
    if curr == nil {curr = IndexPath(row: 0, section: 0)}
    if self.selectedCell == nil {self.selectedCell = curr} else {curr = self.selectedCell}
    let inSection = (curr!.section)
    // increment item in section up to max number of items
    let nextItem = curr!.item + 1
    let maxItem = glyphCollectionOutlet.numberOfItems(inSection: inSection) - 1
    let newItem = min(nextItem, maxItem)
    let newSelectPath = IndexPath(item: newItem, section: inSection)
    self.selectedCell = newSelectPath
    glyphCollectionOutlet.selectItem(at: newSelectPath, animated: true, scrollPosition: .centeredVertically)
    glyphCollectionOutlet.reloadData()
}

这里的问题在于向上和向下导航应该将所选单元格直接放在起点的上方或下方。在 Mac Catalyst 中,viewController 嵌入了 collectionView 可以改变宽度,从而改变一行中 cell/items 的数量。不幸的是,在 collectionView 中,IndexPath.rowIndexPath.item 完全相同,与显示完全无关行。

我需要计算下一个项目的 IndexPath,它应该与当前选择相距 N 个项目。的确,我可以测量当前的 collectionView 宽度,但单元格间距仍然是可变的。有没有办法动态计算或检测一行中显示的项目数,以便我可以计算 N?

可能有办法做到这一点,但我相信还有更好的方法。

为什么不取当前单元格的中心,用项目高度偏移它的y,然后检查哪个索引路径位于那里?

let currentCenter = cell.center
// Let's suppose you want to go downwards, just change to subtraction for going upwards
let targetCenter = CGPoint(currentCenter.x, currentCenter.y + cell.bounds.height) // Or however you want to consider the item height
let targetIndexPath = collectionView.indexPathForItemAtPoint(targetCenter)

此外,这对于非统一尺寸的项目也应该很有效。