我创建了自定义海报视图,因此可以在多个集合视图单元中重用(就像TVUIKit中的TVPosterView)。我将其添加到具有所有必要约束的单元格内容视图中。
问题在于,当单元格被聚焦时,该子视图不会获得焦点更新(didUpdateFocus ..),因此我无法自定义其聚焦/未聚焦的约束等。奇怪的是,内部的图像视图正在获得浮动效果。
如果我将单元格的preferredFocusEnvironments指定为return [self.posterView] + super. preferredFocusEnvironments
,则UI的行为符合预期,但是未调用集合视图委托方法didSelect!
在此先感谢您的帮助!
答案 0 :(得分:0)
似乎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)
}
}