したがって、次のメソッドを持つView Controllerがあります。
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
呼び出されません。
私のサブビューに関して言えば、これは画面を覆うオーバーレイであり (モーダルを使用しなかった理由は聞かないでください。それには理由がありました)、デリゲートとして親ビュー コントローラーを持っています。親View Controllerには次のメソッドがあります。
// 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
有効な非 nil ビューがある場合、オーバーレイがスーパービューから削除された後にフォーカスされる次のビューになることはありません。私が言ったようpreferredFocusedView
に、フォーカスは呼び出されることはなく、代わりに、フォーカス エンジンが次のフォーカスであるべきと判断したものにフォーカスします。
なぜそうなるのか誰でも知っていますか?サブビューを削除すると、フォーカスの更新をトリガーできなくなりますか?
したがって、順序、または少なくとも予想される順序は次のようになります。
- 何か
OverlayView
がインスタンス化をトリガーします beforeOpeningOverlay()
が呼び出され、現在フォーカスされているビューが に設定されfocusedViewBeforeOverlay
ます。オーバーレイが開かれ、フォーカスがキャプチャされます- 何かがオーバーレイビューを閉じるようにトリガーし、呼び出します
closedOverlay()
viewToFocus = focusedViewBeforeOverlay
行が呼び出されます- 親ViewControllerに対してフォーカス更新を呼び出す必要があります。
preferredFocusedView
preferredFocusedView
viewToFocus
which が設定されたものを返しfocusedViewBeforeOverlay
、オーバーレイが開く前にフォーカスされていたビューにフォーカスを戻す必要があります。
問題は、ステップ 5 以降が呼び出されていないようです