嗨,在我的Apple TV应用程序中,我有一个左侧collectionview右侧collectionview.like splitview。每当我将焦点放在左侧数据上的单元格都会在右侧刷新,而当我在右侧collection视图中选择任何一个单元格时,我都会用新数据(如下一级)。单击菜单时,我将使用旧数据刷新两个集合视图(如上一级)。我想用红色突出显示左collectionview中的单元格,但我要在前进或后退时重新加载左collectionview,所以总是第一个单元格用红色突出显示。谁能建议如何在左侧的收藏夹视图中保持先前的选择,因为我只对左侧菜单使用一个收藏夹视图,只是重新加载数据。
答案 0 :(得分:0)
在UITableView或UICollectionView中保留焦点的最简单方法是使用 UICollectionView.remembersLastFocusedIndexPath = true 。这将自动将焦点恢复到集合/表视图中的最后一个焦点项目,并且如果之前没有焦点项目或重新加载了集合视图数据,还将自动将焦点放在第一个项目上。
如果您需要更多控制权,则下一个级别是设置 UICollectionView.remembersLastFocusedIndexPath = false ,并从UIViewController中使用 UICollectionViewDelegate.indexPathForPreferredFocusedView 。不过,仅当焦点以编程方式更改为集合视图时才调用此方法(但如果由于电视远程交互而将焦点更改为集合视图,则不会调用该方法。)
现在要确保在使用电视遥控器在左右收藏夹视图之间切换时调用 indexPathForPreferredFocusedView ,您将需要拦截 shouldUpdateFocusInContext 来覆盖之间的焦点切换左右集合视图以编程方式:
override func shouldUpdateFocusInContext( ... ) -> Bool {
if let nextView: UIView = context.nextFocusedView, let previousView: UIView = context.previouslyFocusedView{
if (nextView.isDescendant(of:leftCollectionView) && previousView.isDescendant(of:rightCollectionView)){
setFocusTo(leftCollectionView) // will invoke delegate indexPath method
return false // prevent system default focus change in favor of programmatic change
}
else if (nextView.isDescendant(of:rightCollectionView && previousView.isDescendant(of:leftCollectionView){
setFocusTo(rightCollectionView) // will invoke delegate indexPath method
return false
}
}
return true
}
internal var focusedView: UIView?
internal func setFocusTo(_ view:UIView){
focusedView = view
setNeedsFocusUpdate()
}
override var preferredFocusEnvironments -> [UIFocusEnvironment]{
return focusedView != nil ? [focusedView!] : super.preferredFocusEnvironments
}
func indexPathForPreferredFocusedView(in collectionView: UICollectionView) -> IndexPath? {
...
}
或者,您可以只使用setFocusTo(collectionViewCell),而不是使用setFocusTo(collectionView)+ indexPathForPreferredFocusedView。覆盖indexPathForPreferredFocusedView更为健壮,因为它可以捕获由于用户交互以外的原因而导致焦点转移的所有情况(例如:由于警报显示和关闭而导致系统焦点更新)