Apple TV 强制聚焦另一个视图

Apple TV force focus another view

我正在从事 Apple TV 项目。该项目包含标签栏视图控制器,通常在遥控器上向上滑动时会出现标签栏,向下滑动时会隐藏标签栏。但现在我扭转了这种行为,我想在向上滑动时强制关注另一个视图(通常关注标签栏)。有什么办法吗?谢谢你。

我之前在 UITabbarController 的焦点上遇到了同样的问题,我在 Apple 支持中找到了解决方案

Because UIViewController conforms to UIFocusEnvironment, custom view controllers in your app can override UIFocusEnvironment delegate methods to achieve custom focus behaviors. Custom view controllers can:

Override the preferredFocusedView to specify where focus should start by default. Override shouldUpdateFocusInContext: to define where focus is allowed to move. Override didUpdateFocusInContext:withAnimationCoordinator: to respond to focus updates when they occur and update your app’s internal state. Your view controllers can also request that the focus engine reset focus to the current preferredFocusedView by callingsetNeedsFocusUpdate. Note that calling setNeedsFocusUpdate only has an effect if the view controller contains the currently focused view.

更多详情,请查看此link https://developer.apple.com/library/content/documentation/General/Conceptual/AppleTV_PG/WorkingwiththeAppleTVRemote.html#//apple_ref/doc/uid/TP40015241-CH5-SW14

在您的 UIViewController 中,覆盖 shouldUpdateFocusInContext。如果您检测到向上导航到标签栏,return false 以防止焦点到达标签栏。然后使用 preferredFocusEnvironments + setNeedsFocusUpdate 的组合将焦点重定向到其他地方:

override func shouldUpdateFocus(in context: UIFocusUpdateContext) -> Bool {
  if let nextView: UIView = context.nextFocusedView{
    if ( context.focusHeading == .up &&  nextView.isDescendant(of: tabBar) ){
      changeFocusTo(myView)
      return false
    }
  }
}

internal var viewToFocus: UIView?
func changeFocusTo(_ view:UIView? ){
    viewToFocus = view
    setNeedsFocusUpdate()
}

override var preferredFocusEnvironments: [UIFocusEnvironment]{
    return viewToFocus != nil ? [viewToFocus!] : super.preferredFocusEnvironments
}

这是一种用于自定义焦点更新的普遍有用的技术。另一种方法是使用 UIFocusGuide。您可以在标签栏下方插入焦点指南,或在标签栏周围添加焦点指南以重定向焦点。虽然焦点指南对简单的案例很有用,但我通常使用我描述的技术获得更好的结果。