14

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

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
  • 3
    Not the answer you're looking for, and I may be wrong on this, but I think it's just not possible to show an action sheet in a popover on iPhone, even in iOS 8. – Scott Berrevoets Sep 18 '14 at 19:49
  • This link may help you out :) http://stackoverflow.com/a/25656733/3964913 – Gordon Worswick Sep 20 '14 at 09:27
  • @GordonWorswick unfortunately not. Per my question, `UIAlertController` doesn't have a `popoverPresentationController` on the iPhone – Ashley Mills Sep 21 '14 at 14:10
  • The link below may be useful;http://useyourloaf.com/blog/2014/09/05/uialertcontroller-changes-in-ios-8.html – Gismay Sep 23 '14 at 16:49
  • 1
    popover is not possible in Iphone , It is the function only implemented for Ipad , If you still wanted a popover try using a custom popup screen. – vinay Jul 28 '15 at 11:55
  • @vinay.bn That is just wrong. Since iOS 8 you can use `UIPopoverPresentationController` to present a popover on an iPhone – Ashley Mills Feb 25 '16 at 09:52
  • @Ashley Mills: Your approach would be true if your application was supporting iOS 8 and above, By the by the comment was of 8 months back when iOS 9 was not launched , generally application would support previous one version atleast. – vinay Feb 29 '16 at 13:06
  • @vinay.bn Irrelevant. Your answer is still wrong. Popovers are possible on the iPhone, and were possible when the question was asked. – Ashley Mills Feb 29 '16 at 13:32

1 Answers1

8

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

Korey Hinton
  • 2,532
  • 2
  • 25
  • 24