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:
viewControllerForAdaptivePresentationStyle
does get called if an @objc
marker is added before it, but that doesn't work for the others.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
}
}
答案 0 :(得分:0)
感谢Paulw11确认问题是由在UIViewController
的扩展中实施代码引起的。这导致了奇怪的行为,从而使代码没有像往常一样被调用。
当迁移到UIViewController
的共享子类时,以下问题已全部解决:
adaptivePresentationStyle
方法。viewControllerForAdaptivePresentationStyle
标记之后才调用@objc
方法。对于寻求相同功能的任何人,正确的代码如下。
class CustomViewController: UIViewController {
func showPopover(ofViewController popoverViewController: UIViewController, originView: UIView) {
popoverViewController.modalPresentationStyle = UIModalPresentationStyle.popover
if let popoverController = popoverViewController.popoverPresentationController {
popoverController.delegate = self
popoverController.sourceView = originView
popoverController.sourceRect = originView.bounds
popoverController.backgroundColor = popoverViewController.view.backgroundColor
popoverController.permittedArrowDirections = UIPopoverArrowDirection.any
}
self.present(popoverViewController, animated: true)
}
}
extension CustomViewController: UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
//return UIModalPresentationStyle.fullScreen
}
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
if traitCollection.horizontalSizeClass == .compact {
return UIModalPresentationStyle.none
//return UIModalPresentationStyle.fullScreen
}
//return UIModalPresentationStyle.fullScreen
return UIModalPresentationStyle.none
}
func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
switch style {
case .fullScreen: // Configuration for full-screen
default:
return controller.presentedViewController
}
}
}