使用Apple TV上的多个控件pipe理焦点
我的屏幕上有多个控件。 在右上方的集合视图,然后是左中心的button,除了button,我有另一个集合视图。 请参阅附件图片
我能够将焦点从button移动到底部收集视图,反之亦然。 我已经为以下内容创build了一个重点指南:
focusGuide.preferredFocusedView = self.btn self.view.addLayoutGuide(self.focusGuide) self.focusGuide.topAnchor.constraintEqualToAnchor(collectionViewHeader.topAnchor).active = true self.focusGuide.bottomAnchor.constraintEqualToAnchor(collectionViewBottom.topAnchor).active = true self.focusGuide.leadingAnchor.constraintEqualToAnchor(collectionViewBottom.leadingAnchor).active = true self.focusGuide.widthAnchor.constraintEqualToAnchor(collectionViewBottom.widthAnchor).active = true
并在didUpdateFocusInContext:,我写:
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) { super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator) guard let nextFocusedView = context.nextFocusedView else { return } if(nextFocusedView .isKindOfClass(bottomCell)) { self.focusGuide.preferredFocusedView = self.btn } else { self.focusGuide.preferredFocusedView = self.collectionViewBottom } }
但是,我无法将焦点从button移动到顶部的集合视图。 我可能需要多个重点指导,但我不知道应该到那里。 谁可以帮我这个事?
谢谢
我在用户界面的很多部分都遇到了类似的问题,所以最后定义了一个自定义视图来创build代表可聚焦控件组的大屏幕区域。 因为我将这些较大的区域设置为覆盖不包含控件的空白区域,所以它们拦截焦点移动并将焦点转移到区域内的控件,而不pipe与焦点从何处开始的原始控件的垂直或水平alignment。
这是自定义视图。 您可以通过在IB中放置一个或多个控件来使用它。
请注意,它具有其他function,如强制焦点到一个特定的控制,而不必重写preferredFocusView,但如果你不需要它们,你可以放弃这些)。
class FocusGroup : UIView { weak private var nextFocusView:UIView? = nil weak var initialView:UIView? = nil var captureFocus:Bool = false func focusOnView(view:UIView, now:Bool=false) { if not(view.isDescendantOfView(self)) || view === self { return } nextFocusView = view setNeedsFocusUpdate() if now { updateFocusIfNeeded() } } func resetFocus(now now:Bool=false) { nextFocusView = nil setNeedsFocusUpdate() if now { updateFocusIfNeeded() } } override func canBecomeFocused() -> Bool { if nextFocusView != nil { return true } if containsFocus { return false } return firstFocusableSubView() != nil } func firstFocusableSubView() -> UIView? { return findSubview({ $0.canBecomeFocused() && $0.userInteractionEnabled && $0.visible && ( not($0 is UIButton) || ($0 as! UIButton).enabled ) }) } override var preferredFocusedView: UIView? { if let viewToFocus = ( nextFocusView ?? initialView ) ?? firstFocusableSubView() { return viewToFocus } return nil } override func shouldUpdateFocusInContext(context: UIFocusUpdateContext) -> Bool { // when capturing focus, prevent navigation outside of grouped subviews if captureFocus && containsFocus && context.previouslyFocusedView!.isDescendantOfView(self) && ( context.nextFocusedView == nil || context.nextFocusedView === self || not(context.nextFocusedView!.isDescendantOfView(self)) ) { return false } return true } override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) { // give focus to specific view as requested if nextFocusView != nil { if context.nextFocusedView === nextFocusView || not(nextFocusView!.canBecomeFocused()) { nextFocusView = nil } return } } }