所以我有一个具有以下方法的视图控制器:
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
的永远不会调用,而是专注于焦点引擎决定的下一个焦点。
有谁知道为什么会这样?删除子视图是否不允许您触发焦点更新?
所以顺序,或者至少是预期的顺序,应该是:
- 触发
OverlayView
要实例化的东西 beforeOpeningOverlay()
被调用,当前焦点视图设置为focusedViewBeforeOverlay
. 然后打开覆盖并捕获焦点- 有些东西会触发覆盖视图关闭,调用
closedOverlay()
viewToFocus = focusedViewBeforeOverlay
线被称为- 应该为父视图控制器调用焦点更新,调用它的
preferredFocusedView
preferredFocusedView
应该返回viewToFocus
设置为focusedViewBeforeOverlay
并将焦点恢复到覆盖打开之前聚焦的视图
问题似乎是没有调用第 5 步及以后的步骤