我正在构建一个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
函数中的所有内容。
有人能帮我吗。感谢
对于collectionView,属性remembersLastFocusedIndexPath应设置为true,对于tableView,属性为false。
此外,您是否在viewWillAppear中重新加载UITableView,即当弹出B并出现A时,表数据是否正在刷新?如果是,则在重新加载时lastFocusedIndexPath将为零。
我们面临着同样的问题。我们通过在弹出B时不重新加载内容来解决这个问题。
保持一个标志,比如didPush。当按下B时,将此标志设置为true。当A出现时,检查标志是否已设置,然后提取数据并重新加载表
这对我们有效。
我记不清了,但我知道remembersLastFocusedIndexPath
有一个已知的问题,它没有按预期工作。
这是一种变通方法,尽管要谨慎对待,因为它看起来确实有点笨拙,而且它使用了覆盖preferredFocusedView
属性的常见(但可能不稳定)方法。
private var viewToFocus: UIView?
override var preferredFocusView: UIView? {
get {
return self.viewToFocus
}
}
当呈现View B
时,本地保存View A
中最后单元格的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
的原因是它消除了一点动画跳跃。如果其他人能提出改进甚至替代解决方案的建议,我也会感兴趣!
在Swift中
如果要聚焦集合视图"单元格",则您可以使用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)
}
}