swift2 在Apple TV上使用多个控制来管理焦点

eiee3dmh  于 2022-11-06  发布在  Swift
关注(0)|答案(2)|浏览(279)

我的屏幕上有多个控件。右上角有一个集合视图,然后左中有一个按钮,除了这个按钮,我还有另一个集合视图。请参考所附的it

图像
我可以将焦点从按钮移动到底部集合视图,反之亦然。我已经创建了一个焦点指南,如下所示:

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
        }
    }

但是,我不能将焦点从按钮移到顶部集合视图。我可能需要多个焦点向导,但我不知道应该有什么。有人能帮助我吗?
谢谢你

ikfrs5lh

ikfrs5lh1#

我在UI的很多部分都遇到了类似的问题,所以最后我定义了一个自定义视图,以创建更大的屏幕区域来表示可获得焦点的控件组。因为我设置了这些更大的区域来覆盖不包含控件的空白区域,所以它们会拦截焦点移动,并将焦点转移到该区域内的控件上,而与焦点开始的原始控件无关,无论是垂直还是水平对齐。
这是自定义视图。在IB中,您可以通过在其中放置一个或多个控件来使用它。
请注意,它还有一些附加功能,例如强制焦点指向特定控件而不必覆盖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
      }      
   }

}
s4n0splo

s4n0splo2#

只需在按钮上方和顶部收藏视图的左侧插入一个焦点参考线,将焦点重定向到顶部收藏视图:

focusGuide.preferredFocusedView = self.topView
    self.view.addLayoutGuide(focusGuide)

    self.focusGuide.topAnchor.constraintEqualToAnchor(topView.topAnchor).active = true
    self.focusGuide.bottomAnchor.constraintEqualToAnchor(topView.bottomAnchor).active = true
    self.focusGuide.leadingAnchor.constraintEqualToAnchor(btn.leadingAnchor).active = true
    self.focusGuide.trailingAnchor.constraintEqualToAnchor(btn.trailingAnchor).active = true

您可能还需要在按钮右侧和顶部收藏视图下方插入焦点参考线,以便从顶部行向下导航时将焦点重定向到按钮,而不是底部行。

相关问题