iosswiftpopoveruipopoverpresentationcontroller

Presenting a popover without segue -- Popover is still full screen


I have a UIViewController with a button in it that I made programmatically (Let's just call it MyViewController). I am trying to present a popover when the button is tapped. Let's call the popover DestinationViewController. The button will call the following function when tapped:

func buttonAction(_ button: UIView) {
   var popover = storyboard?.instantiateViewController(withIdentifier: "destinationVC") as? DestinationViewController
   popover?.popoverPresentationController?.delegate = self
   popover?.modalPresentationStyle = .popover
   popover?.popoverPresentationController?.sourceView = button
   //popover?.popoverPresentationController?.sourceRect = CGRect(x: 0, y: 0, width: 50, height: 50)
   popover?.preferredContentSize = CGSize(width: 200, height: 100)

   present(popover!, animated: true, completion: nil)         
}

(I commented out the sourceRect line because it wasn't doing anything but I don't know if I'm just using it wrong.)

Additionally, I made sure that MyViewController conforms to the protocol UIPopoverPresentationControllerDelegate. So MyViewController implements the function:

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
   return .none
}

Finally, in my storyboard for the DestinationViewController, I have checked the box "Use Preferred Explicit Size" with 200 width and 100 height.

However, my DestinationViewController is still being displayed full screen. I have read that the adaptivePresentationStyle function is supposed to prevent this, but no luck. I know that using a segue will make it work correctly, but I can't make a segue in storyboard because my button was made programmatically.

Any ideas on what I should do to fix this? I'm not that familiar with making popovers so I need a bit of help.


Solution

  • You need to set the modalPresentationStyle to .popover before you access the popoverPresentAtionController property:

    From the documentation:

    If you created the view controller but have not yet presented it, accessing this property creates a popover presentation controller when the value in the modalPresentationStyle property is UIModalPresentationStyle.popover. If the modal presentation style is a different value, this property is nil.

    As you haven't set the modal presentation style before you set the delegate, no popover presentation controller is created. The popover controller will be created when you set the .sourceView, as the presentation style is now .popover but the delegate won't be set on this instance.

    Also, you can use a segue with a button you create in code by using performSegue in the buttons action handler code.