Reputation: 1299
So I have a view controller that has the following methods:
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;
}
}
So essentially I can force a focus update to the view I want by setting viewToFocus
to a value, which works great in most cases. However, when removing a subview this doesn't seem to work properly and preferredFocusedView
is never called.
In terms of my subview, it's an overlay that covers the screen (don't ask why I didn't use a modal, there were reasons for that) and has the parent view controller as a delegate. The parent view controller has the following methods:
// 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()
}
For some reason when closedOverlay is called, and focusedViewBeforeOverlay
has a valid non-nil view, it is never the next view focused on after the overlay is removed from the superview. Like I said preferredFocusedView
is never called, and focus instead focuses on whatever the focus engine decides should be the next focus.
Anyone know why that might be the case? Does removing a subview not allow you to trigger a focus update?
So the order, or at least expected order, should be:
OverlayView
to be instantiatedbeforeOpeningOverlay()
is called, and the currently focused view is set to focusedViewBeforeOverlay
. The overlay is then opened and captures focusclosedOverlay()
viewToFocus = focusedViewBeforeOverlay
line is calledpreferredFocusedView
preferredFocusedView
should return viewToFocus
which was set to focusedViewBeforeOverlay
and revert focus back to the view that was focused before the overlay opensThe issue seems to be that step 5 and onwards aren't called
Upvotes: 0
Views: 3434
Reputation: 502
As Roman commented, referredFocusedView
was deprecated in tvOS 10. Now you have to define your preferredFocusEnvironments
.
That in your case would be something like:
override var preferredFocusEnvironments: [UIFocusEnvironment] {
if let focusEnviroment = self.viewToFocus { return [focusEnviroment] }
return super.preferredFocusEnvironments
}
You also need to call self.setNeedsFocusUpdate()
for updating the focus.
Upvotes: 2