我正在构建一个tvos
应用程序。我有一个奇怪的错误,当我导航回特定视图时,UICollectionView
失去了先前所选单元格的焦点。这种情况是这样的。
我有两个UIViewControllers
A
和B
。 A
有UITableView
,其中有三个原型单元格。每个单元格内部都有一个水平滚动UICollectionView
。当我点击UICollectionViewCell
中的任何一个时,它会导航到B
(详细信息页面)。我以模态方式呈现B
。
现在当我按下Siri远程视图上的菜单按钮A
时,再次出现(换句话说,视图B
已从视图层次结构中移除),但当前所选单元格与之前选择的单元格不同。我尝试将remembersLastFocusedIndexPath
用于true
和false
值,并尝试通过实施
func indexPathForPreferredFocusedViewInCollectionView(collectionView: UICollectionView) -> NSIndexPath?
但是当我导航回到视图A时,控件neves来到这个函数。我也在重新加载viewWillAppear
函数中的所有东西。
任何人都可以帮助我。感谢
答案 0 :(得分:3)
对于collectionView,属性 remembersLastFocusedIndexPath 应设置为 true ,对于tableView应设置为 false 。
另外,您是否在viewWillAppear中重新加载UITableView,即弹出B并且出现A时是否刷新表数据? 如果是,则重新加载时,lastFocusedIndexPath将为零。
我们遇到了同样的问题。我们通过在弹出B时不重新加载内容来解决它。
保持一个标志说didPush。按下B时将此标志设置为true。当出现A时,检查是否设置了标志,然后才获取数据并重新加载表。
这对我们有用。
答案 1 :(得分:1)
我不记得确切,但我知道remembersLastFocusedIndexPath
存在一个已知问题,因为它无法正常工作。
这是一种解决方法,虽然它采用了大量的盐,因为它似乎有点 hacky 并且它使用覆盖preferredFocusedView
属性的常见(但可能不稳定)方法。
private var viewToFocus: UIView?
override var preferredFocusView: UIView? {
get {
return self.viewToFocus
}
}
在呈现View A
View B
中本地保存 last 单元格的indexPath
// [1] Saving and scrolling to the correct indexPath:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
...
collectionView.scrollToItemAtIndexPath(indexPath:, atScrollPosition:, animated:)
}
// [2] Create a dispatchTime using GCD before setting the cell at indexPath as the preferredFocusView:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
...
let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(CGFloat.min * CGFloat(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
self.viewToFocus = collectionView.cellForItemAtIndexPath(indexPath:)
// [3] Request an update
self.setNeedsFocusUpdate()
// [4] Force a focus update
self.updateFocusIfNeeded()
}
}
我们将这两种方法分成viewWillAppear
和viewDidAppear
的原因是它消除了一点动画跳转。如果其他人可以提出改进或甚至替代解决方案的建议,我也会感兴趣!
答案 2 :(得分:0)
在Swift中
如果你想关注集合视图Cell那么 您可以使用collectionview Delegate方法,方法名称是
func collectionView(collectionView: UICollectionView, didUpdateFocusInContext context: UICollectionViewFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
{
}
您可以像这样使用此方法......
func collectionView(collectionView: UICollectionView, didUpdateFocusInContext context: UICollectionViewFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
if let previousIndexPath = context.previouslyFocusedIndexPath,
let cell = collectionView.cellForItemAtIndexPath(previousIndexPath) {
cell.contentView.layer.borderWidth = 0.0
cell.contentView.layer.shadowRadius = 0.0
cell.contentView.layer.shadowOpacity = 0
}
if let indexPath = context.nextFocusedIndexPath,
let cell = collectionView.cellForItemAtIndexPath(indexPath) {
cell.contentView.layer.borderWidth = 8.0
cell.contentView.layer.borderColor = UIColor.blackColor().CGColor
cell.contentView.layer.shadowColor = UIColor.blackColor().CGColor
cell.contentView.layer.shadowRadius = 10.0
cell.contentView.layer.shadowOpacity = 0.9
cell.contentView.layer.shadowOffset = CGSize(width: 0, height: 0)
collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: [.CenteredHorizontally, .CenteredVertically], animated: true)
}
}