adaptivePresentationStyle 不会在 Compact (iPhone) 设备上触发 UIPopoverPresentationControllerDelegate

adaptivePresentationStyle not Triggering for UIPopoverPresentationControllerDelegate on Compact (iPhone) Devices

我正在尝试将一个 UIViewController 显示为另一个的弹出窗口。为此,我建立了以下...

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)
}

但是,新的 VC 在紧凑型设备上始终显示为全屏模式演示,而不是实际的弹出窗口。根据我阅读的内容 here & ,这是正常行为,但应该可以通过委托进行自定义。

我已将呈现 VC 声明为实现 UIPopoverPresentationControllerDelegate,将其设置为委托,并实现了所需的方法;但是,永远不会调用委托方法。这意味着 'popover' 仍然以模态方式显示,无论如何。

欢迎任何建议。

其他一些标注:

谢谢。

已实现委托功能:

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
    }
}

感谢 Paulw11 确认问题是由在 UIViewController 扩展 中实施代码引起的。这导致了奇怪的行为,代码没有像往常一样被调用。

迁移到 UIViewController 的共享 子类 时,以下问题全部得到解决:

  • adaptivePresentationStyle 方法从未被调用。
  • viewControllerForAdaptivePresentationStyle 方法只有在前面有 @objc 标记时才会被调用。
  • Xcode 给出 实例方法...几乎匹配可选要求...协议 'UIAdaptivePresentationControllerDelegate' 错误。

更正后的代码如下,供寻求相同功能的任何人使用。

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
        }
    }
}