I have a UIView with two buttons on it. In the MyView
class I have this code:
-(BOOL) canBecomeFocused {
return YES;
}
-(NSArray
If anybody is facing this issue, Just check if you are getting the following debug message printed in the console.
WARNING: Calling updateFocusIfNeeded while a focus update is in progress. This call will be ignored.
I had the following code :
// MARK: - Focus Environment
var viewToBeFocused: UIView?
func updateFocus() {
setNeedsFocusUpdate()
updateFocusIfNeeded()
}
override var preferredFocusEnvironments: [UIFocusEnvironment] {
if let viewToBeFocused = self.viewToBeFocused {
self.viewToBeFocused = nil
return [viewToBeFocused]
}
return super.preferredFocusEnvironments
}
I was calling the updateFocus()
method multiple times while viewToBeFocused
was either nil or some other view. Debugging the focus issues mainly between transition is really difficult. You should have patience.
Important to note: This depends on your use case, but if you want to update the focus right after a viewcontroller transition (backward navigation), You might have to set the following in viewDidLoad:
restoresFocusAfterTransition = false // default is true
If this is true, the view controller will have the tendancy to focus the last focused view even if we force the focus update by calling updateFocusIfNeeded()
. In this case , since a focus update is already in process, you will get the warning as mentioned before at the top of this answer.
Use the following link to debug the focus issues: https://developer.apple.com/documentation/uikit/focus_interactions/debugging_focus_issues_in_your_app
Enable the focus debugger first under Edit scheme > Arguments passed on launch:
-UIFocusLoggingEnabled YES
This will log all the attempts made by the focus engine to update the focus. This is really helpful.
You can override the preferredFocusEnviromnets with the following logic:
-(NSArray<id<UIFocusEnvironment>> *)preferredFocusEnvironments {
if (condition) {
return @[_editButton];
}
else {
return @[_addButton];
}
}
After setting it, you can call
[_myView setNeedsFocusUpdate];
[_myView updateFocusIfNeeded];
The condition could be BOOL condition = tableViewController.editing;
or sg like that.
If that now works, you can call it with a delay (0.1 sec or so).