首页 > 解决方案 > 确保 popover 的presentingViewController 是原始演示者

问题描述

我有一个容器视图控制器。其中一个子视图控制器需要呈现一个弹出框。问题是弹出框presentingViewController最终成为容器视图控制器,而不是呈现它的子视图控制器。

*我已经在子视图控制器(及其导航控制器)上设置了definesPresentationContext属性,但这并没有改变任何东西(这只有在呈现的控制器是或时才有用truemodalPresentationStyle.currentContextoverCurrentContext

文档UIViewController present(_:animated:completion:)讨论了演示文稿如何来自另一个控制器,具体取决于演示文稿样式。因此,我希望有一种方法可以覆盖或拦截该确定,以便在这种情况下,我可以确保弹出框presentingViewController是最初呈现它的控制器。

我在容器视图控制器中还有其他功能,这些功能与适应受此问题阻碍的尺寸类变化有关。

有什么方法可以确保弹出框presentingViewController是原始演示者?这可能与presentationController创建方式有关,但我不知道如何利用该过程。

下面是演示问题的代码。如果您希望重现问题,请在 Xcode 中创建一个新的 iOS Single View App 项目。然后用ViewController.swift下面的代码替换提供的内容。在 iPad 模拟器上运行。将添加一个带有一个子视图控制器的容器视图控制器,并从子视图中显示一个弹出窗口。调试器控制台将显示一些输出。注意弹出窗口presentingViewController是容器而不是孩子。

注意:虽然以下内容在 Swift 中,但 Objective-C 响应也很好。

import UIKit

class ViewController: UIViewController {
    var childViewController: UIViewController!

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)

        coordinator.animate(alongsideTransition: { (context) in
            self.childViewController.navigationController?.view.frame = CGRect(x: size.width / 2, y: 0, width: size.width / 2, height: size.height)
        }, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        childViewController = UIViewController()
        childViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Test", style: .plain, target: nil, action: nil)
        let nav = UINavigationController(rootViewController: childViewController)

        addChildViewController(nav)
        view.addSubview(nav.view)
        nav.didMove(toParentViewController: self)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let popup = UIViewController()
        popup.definesPresentationContext = true
        let nav = UINavigationController(rootViewController: popup)
        nav.modalPresentationStyle = .popover
        nav.definesPresentationContext = true
        nav.popoverPresentationController?.barButtonItem = childViewController.navigationItem.leftBarButtonItem
        childViewController.present(nav, animated: true) {
            print("Popup displayed")
            print("container: \(self)")
            print("child: \(self.childViewController), child.nav: \(self.childViewController.navigationController)")
            print("presentingViewController: \(nav.presentingViewController)")
        }
    }
}

标签: iosuiviewcontrolleruicontainerviewuimodalpresentationstyle

解决方案


推荐阅读