I'm creating and presenting an ActionSheet
as follows:
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
alertController.modalPresentationStyle = .Popover
// Add some buttons
alertController.popoverPresentationController?.delegate = self
alertController.popoverPresentationController?.barButtonItem = someBarButton
self.presentViewController(alertController, animated: true, completion: nil)
This works fine on the iPad, but alertController.popoverPresentationController
is nil
on the iPhone.
I've successfully presented popovers on the iPhone using adaptive segue style Present As Popover in interface builder and implementing adaptivePresentationStyleForPresentationController
delegate method to return the correct UIModalPresentationStyle
but I'm stuck how to do it in code with UIAlertController
as it has no popoverPresentationController
on the iPhone
UIAlertController is not meant to be a popover. There seems to be some controversy about this in the comments. Your code above wouldn't work if it was actually respecting the .Popover
style. Why? Because it needs to have a sourceView
and a sourceRect
set on the popoverPresentationController object to know where to point the arrow. If you swap UIAlertController out for UIViewController it'll crash because those values aren't set. Ironically if you do try force unwrap the popoverPresentationController it'll crash:
alertController.modalPresentationStyle = .Popover
alertController.popoverPresentationController!.sourceView = sender // CRASH!!!
alertController.popoverPresentationController!.sourceRect = sender.bounds
For all details on how to implement an iPhone popover (for everything else but UIAlertController) look at my iPhone Popover blog post.
The fact that the popover presentation controller is nil is pretty telling that its not supposed to be a popover.
Table View Alternative
You might consider UITableViewController as a replacement here. Using the Grouped style actually looks pretty nice in popovers.
Picker
You are going to run into this problem probably over and over again, where you want the user to just select from a few options. I'd suggest you encapsulate whatever user interface control you're going to use into your own picker object. The implementation details of whether its a table view or just a line-up of buttons can be disguised from the calling code and you can have a delegate or closure callbacks when selection at a particular index occurs. Here's roughly what the API might look like:
class Picker: UIViewController {
init(items: [String])
selectionCompletion: (index: Int, item: String)->Void
}
// Usage:
let picker = Picker(["Answer A","Answer B"])
picker.selectionCompletion = { index, item in
// handle selection
}
This way you can reuse it anywhere you'd like and the API is very simple
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With