I'm attempting to display one UIViewController as a popover from another. For that, I've established the following...
func showPopover(ofViewController popoverViewController: UIViewController, sender: UIView) {
popoverViewController.modalPresentationStyle = .popover
popoverViewController.popoverPresentationController?.sourceView = sender
popoverViewController.popoverPresentationController?.sourceRect = sender.bounds
popoverViewController.popoverPresentationController?.delegate = self
self.present(popoverViewController, animated: true, completion: nil)
}
However, the new VC always shows as a full-screen, modal presentation on compact devices, rather than an actual popover. Based on what I've read here & here, that's normal behaviour, but should be customizable through delegation.
I've declared the presenting VC as implementing UIPopoverPresentationControllerDelegate, set it as the delegate, and implemented the required methods; however, the delegation methods are never getting called. This means the 'popover' is still getting shown modally, regardless.
Any advice would be welcome.
Some other callouts:
- The
viewControllerForAdaptivePresentationStyledoes get called if an@objcmarker is added before it, but that doesn't work for the others. - Xcode is giving a warning for each one: Instance method ... nearly matches optional requirement ... of protocol 'UIAdaptivePresentationControllerDelegate'; however, the method signature is a 100% match. Not sure if this is an instance of this bug, which some say still exists in Xcode 10.1.
Thanks.
Delegate functions implemented:
func adaptivePresentationStyle(for: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.popover
}
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
return UIModalPresentationStyle.popover
}
func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
switch style {
case .fullScreen: // Configuration for full-screen
default: return controller.presentedViewController
}
}
Thanks to Paulw11 for confirming that the problem was caused by implementing the code in an extension of
UIViewController. This was resulting in strange behaviours, whereby the code wasn't being called as usual.When migrated to a shared subclass of
UIViewController, the following problems were all resolved:adaptivePresentationStylemethod never being called.viewControllerForAdaptivePresentationStylemethod only being called if preceded by the@objctag.Corrected code is as follows, for anyone seeking the same functionality.