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
viewControllerForAdaptivePresentationStyle
does get called if an@objc
marker 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:adaptivePresentationStyle
method never being called.viewControllerForAdaptivePresentationStyle
method only being called if preceded by the@objc
tag.Corrected code is as follows, for anyone seeking the same functionality.