2016-05-03 80 views
1

我的屏幕上有多個控件。右上角的集合視圖,然後是左中心的按鈕,除了按鈕,我還有另一個集合視圖。請參閱附加圖像enter image description here在Apple TV上使用多個控件管理焦點

我能夠將焦點從按鈕移到底部集合視圖,反之亦然。我已經創建了一個下同重點指南:


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

但是,我無法從鍵將焦點移到頂部集合視圖。我可能需要多個重點指導,但我不知道應該到那裏。誰可以幫我這個事?

謝謝

回答

0

我在我的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 
     }  
    } 

}