如何强制视图控制器调用preferredFocusView?

时间:2016-07-25 01:55:30

标签: ios swift uiviewcontroller tvos focus-engine

所以我有一个视图控制器,它有以下方法:

    var viewToFocus: UIView? = nil {
        didSet {
            if viewToFocus != nil {
                self.setNeedsFocusUpdate()
                self.updateFocusIfNeeded()
            }
        }
    }

    override weak var preferredFocusedView: UIView? {
        if viewToFocus != nil {
            let theView = viewToFocus
            viewToFocus = nil
            return theView
        } else {
            return super.preferredFocusedView;
        }
    }

基本上我可以通过将viewToFocus设置为一个值来强制将焦点更新到我想要的视图,这在大多数情况下都很有效。但是,在删除子视图时,这似乎无法正常工作,并且永远不会调用preferredFocusedView

就我的子视图而言,它是覆盖屏幕的覆盖图(不要问为什么我没有使用模态,有原因)并且将父视图控制器作为委托。父视图控制器具有以下方法:

// Delegate of 'OverlayView'. Called BEFORE it is added as a subview
func beforeOpeningOverlay() {
    focusedViewBeforeOverlay = UIScreen.mainScreen().focusedView
}

// Delegate of 'OverlayView'. Called after its close action is triggered.
func closedOverlay(overlay: OverlayView) {
    if focusedViewBeforeOverlay != nil {
        viewToFocus = focusedViewBeforeOverlay
        focusedViewBeforeOverlay = nil
    }
    overlay.delegate = nil
    overlay.removeFromSuperview()
}

出于某种原因,当调用closedOverlay并且focusedViewBeforeOverlay具有有效的非零视图时,从超级视图中删除叠加层后,它永远不会是下一个关注的视图。就像我说preferredFocusedView永远不会被调用,而焦点则集中在焦点引擎决定的下一个焦点上。

任何人都知道为什么会这样吗?删除子视图是否允许您触发焦点更新?

所以订单或至少预期的订单应该是:

  1. 触发OverlayView实例化的东西
  2. 调用
  3. beforeOpeningOverlay(),将当前关注的视图设置为focusedViewBeforeOverlay。然后打开叠加层并捕捉焦点
  4. 触发覆盖视图关闭,调用closedOverlay()
  5. viewToFocus = focusedViewBeforeOverlay行被称为
  6. 应为父视图控制器调用焦点更新,并调用其preferredFocusedView
  7. preferredFocusedView应该返回设置为viewToFocus的{​​{1}},并将焦点恢复到重叠打开前关注的视图
  8. 问题似乎是第5步及以后不会被称为

1 个答案:

答案 0 :(得分:1)

正如Roman所评论的那样,referredFocusedView在tvOS 10中已被弃用。现在您必须定义preferredFocusEnvironments

在你的情况下,这将是:

override var preferredFocusEnvironments: [UIFocusEnvironment] {
    if let focusEnviroment = self.viewToFocus { return [focusEnviroment] }
    return super.preferredFocusEnvironments
}

您还需要致电self.setNeedsFocusUpdate()以获取更新焦点。