tvOS UICollectionView获取当前焦点项目的索引路径

时间:2015-09-26 20:26:54

标签: uicollectionview tvos

所以这是一个非常愚蠢的问题,但我无法找到一种非常简单的方法来检测当前关注的项目indexPath。 我环顾四周,希望看到像collectionView.indexPathOfCurrentlyFocusedItem这样的东西非常容易,但却找不到任何远近的东西。 所以我在UIFocusEnvironmentUIFocusUpdateContext试图寻找所需的属性但是失败了,并试图找到类似的东西。 因此,我能想出的唯一解决方案是遍历所有可见单元格并找到焦点属性设置为true的单元格。

那么有更简单优雅的方法来找到当前关注的项目indexPath吗? (除非通过委托方法跟踪并将其保存在视图控制器的属性中)

4 个答案:

答案 0 :(得分:19)

您可以使用UIScreen属性focusedView,如下所示:

if let focusedCell = UIScreen.main.focusedView as? UICollectionViewCell {
    if let indexPath = collectionView.indexPath(for: focusedCell) {
        print("IndexPath is \(indexPath)")
    }
}

答案 1 :(得分:8)

使用didUpdateFocusInContect - UICollectionViewDelegate

func collectionView(collectionView: UICollectionView, didUpdateFocusInContext context: UICollectionViewFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    if collectionView == self.collectionView {
        print(context.nextFocusedIndexPath)
    }
}

这将返回将要聚焦的单元格的indexPath,您也可以尝试:

context.previouslyFocusedIndexPath

取决于你想要做的事情。

答案 2 :(得分:3)

所以,你的目标是当你得到并失去焦点时特别是在tvOS下的一个细胞上。问题是你正在移动其他UI元素,因此上下文可能会有所不同。您必须在此上下文中仅更改您必须关注的UI。

进行实现的正确位置是func didUpdateFocusInContext(),如下所示:

override func didUpdateFocusInContext(
  context:                              UIFocusUpdateContext,
  withAnimationCoordinator coordinator: UIFocusAnimationCoordinator
) {
  coordinator.addCoordinatedAnimations({
    if let cell = context.previouslyFocusedView as? UICollectionViewCell {
      cell.layer.borderWidth = 2
    }

    if let cell = context.nextFocusedView as? UICollectionViewCell {
      cell.layer.borderWidth = 5
    }
  },
  completion: nil)
}

现在我们正在使用焦点协调器来应用我们的逻辑:

  • 当先前关注的项目是UICollectionViewCell时,您必须将焦点释放到下一个项目。您不应该关心下一个项目是什么,因为它可能是一个集合单元格。为了好玩,在这种情况下,让我们将边框更改为2.默认情况下可以设置此值。
  • 当下一个聚焦项目是UICollectionViewCell时,你将以类似的方式处理它,否则它将变得一团糟...所以,让我们将边框改为5.

如您所见,didUpdateFocusInContext()为当前可视上下文中的所有视图提供了通用方法。您可以对其他UI元素应用相同的方法。

享受tvOS的乐趣......

答案 3 :(得分:2)

以下是我在shouldUpdateFocusInContext

中完成此操作的方法

解决方案

override func shouldUpdateFocusInContext(context: UIFocusUpdateContext) -> Bool {

    // The magic is in the next two lines
    let cell: UICollectionViewCell = context.nextFocusedView as! UICollectionViewCell
    let indexPath: NSIndexPath? = self.collectionView.indexPathForCell(cell)

    print(indexPath) 
    // <NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}

    return true
}