I want to display a UIAlertController
on top of a UIViewController
with a UICollectionView
inside. The collection view needs to focus on startup, so I overrode the preferredFocusableView
variable as follows:
override var preferredFocusedView: UIView? {
return self.collectionView
}
With tvOS 9 all worked fine: the alert controller opened properly and I was able to choose one of the UIAlertAction
s displayed.
On tvOS 10 Golden Master, after opening the alert controller and scrolling to another action, the focus disappears from the screen and I'm unable to scroll to other actions or tapping on the Menu button of the Siri Remote. The app remains stuck in the alert controller and I can hear the scrolling sound when I try to scroll to other actions but nothing happens on screen. I have to force quit the app and reopen it.
This is the code of the app. I tried to set the preferredFocusableView
to alertController.preferredFocusedView
or by removing the focus methods of the collection view but with no results.
var alertController : UIAlertController?
func showAlert() {
alertController = UIAlertController(title:"Example title", message: "Example description", preferredStyle: .Alert)
let action1 = UIAlertAction(title: "Option 1", style: .Default) { (action : UIAlertAction) -> Void in
//call to another method
}
// action2, action3, action4...
let action5 = UIAlertAction(title: "Option 5", style: .Default) { (action : UIAlertAction) -> Void in
//call to another method
}
let actionDismiss = UIAlertAction(title: "Dismiss", style: .Destructive) { (action : UIAlertAction) -> Void in
self.alertController!.dismissViewControllerAnimated(true, completion: nil)
}
alertController!.addAction(action1)
alertController!.addAction(action2)
alertController!.addAction(action3)
alertController!.addAction(action4)
alertController!.addAction(action5)
alertController!.addAction(actionDismiss)
alertController!.preferredAction = action1
self.presentViewController(alertController!, animated: true, completion: nil)
}
override var preferredFocusedView: UIView? {
if self.alertController != nil {
return self.alertController!.preferredFocusedView
} else {
return self.collectionView
}
}
Apple just replied to my radar:
Inside the attached application, you’re overwriting the functionality of
UIScrollView
in an extension to returntrue
forcanBecomeFocused()
, which is the cause of these unexpected side effects. The focus seems to be disappearing when moving to a secondUIAlertController
option; however, it is actually transferring focus to the scroll view wrapped around the various components of theUIAlertController
, since this is now allowed due to the extension mentioned above.To solve this, create a custom subclass of
UIScrollView
to be used only in the instances wherecanBecomeFocused()
must returntrue
.