【问题标题】:UICollectionViewCell custom subview doesn't receive focusUICollectionViewCell 自定义子视图没有获得焦点
【发布时间】:2020-06-26 18:35:11
【问题描述】:
我创建了自定义海报视图,因此它可以在多个集合视图单元格中重复使用(就像 TVUIKit 中的 TVPosterView)。我将它直接添加到具有所有所需约束的单元格内容视图中。
问题是当单元格获得焦点时,这个子视图没有接收焦点更新 (didUpdateFocus..),所以我无法自定义它的焦点/非焦点约束等。奇怪的是,内部的图像视图正在获得浮动效果。
如果我将单元格的preferredFocusEnvironments 指定为return [self.posterView] + super. preferredFocusEnvironments,UI 会按预期运行,但集合视图委托方法didSelect 未调用!
提前感谢您的帮助!
【问题讨论】:
标签:
uicollectionviewcell
tvos
【解决方案1】:
似乎 didUpdateFocus 没有调用焦点单元的所有子视图及其系统设计。来自文档:
焦点更新到新视图后,焦点引擎调用这个
方法适用于所有包含先前的焦点环境
焦点视图、下一个焦点视图或两者,按升序顺序。你
应覆盖此方法以更新您的应用程序的状态以响应
焦点的变化。使用提供的动画协调器制作动画
与更新相关的视觉外观变化。更多
有关动画协调员的信息,请参阅
UIFocusAnimationCoordinator。
注意:这意味着didUpdateFocus 将首先在 UICollectionViewCell 上被调用,而不是在 UIViewController 子类上,按升序顺序。对于子视图,您需要手动注册将在通知更新中触发的customDidUpdateFocus 方法。例如。要更新它的外观,我们可以使用通知 (tvOS 11+),请参阅下面的示例。
func customDidUpdateFocus(isFocused: Bool, with coordinator: UIFocusAnimationCoordinator) { /* Custom logic to customize appearance */ }
// Register observer
observerToken = NotificationCenter.default.addObserver(forName: UIFocusSystem.didUpdateNotification, object: nil, queue: .main) { [weak self] (note) in
guard let self = self else { return }
guard let context = note.userInfo?[UIFocusSystem.focusUpdateContextUserInfoKey] as? UIFocusUpdateContext else { return }
guard let coordinator = note.userInfo?[UIFocusSystem.animationCoordinatorUserInfoKey] as? UIFocusAnimationCoordinator else { return }
if let prev = context.previouslyFocusedView, self.isDescendant(of: prev) {
self.didUpdateFocus(isFocused: false, with: coordinator)
} else if let next = context.nextFocusedView, self.isDescendant(of: next) {
self.didUpdateFocus(isFocused: true, with: coordinator)
}
}