作为popover呈现的UIViewController可以是它自己的popoverPresentationController委托吗?

时间:2017-08-02 19:06:13

标签: swift uiviewcontroller popover uipresentationcontroller

在下面显示的项目中,InitialViewController有一个标有" Show Popover"的按钮。当点击该按钮时,应用程序应该将第二个视图控制器(PopoverViewController)显示为弹出窗口。第二个视图控制器只有一个标签,上面写着" Popover!"。

storyboard image

如果InitialViewController负责实例化PopoverViewController,检索popoverPresentationController然后将popoverPresentationController delegate设置为自身(InitialViewController,则此工作正常1}})。您可以在下面看到结果:

functiong app when delegation occurs in InitialViewController

但是,为了获得最大的可重用性,如果InitialViewController不需要知道如何委派表示控制器,那就太棒了。我认为PopoverViewController应该可以将自己设置为popoverPresentationController' s delegate。我已经在viewDidLoad的{​​{1}}或viewWillAppear函数中尝试了此操作。但是,PopoverViewController在两种情况下均以模态显示,如下所示:

enter image description here

所有代码仅包含在PopoverViewControllerInitialViewController中。 PopoverViewController失败版本中使用的代码如下所示:

InitialViewController

失败 import UIKit // MARK: - UIViewController subclass class InitialViewController: UIViewController { struct Lets { static let storyboardName = "Main" static let popoverStoryboardID = "Popover View Controller" } @IBAction func showPopoverButton(_ sender: UIButton) { // instantiate & present the popover view controller let storyboard = UIStoryboard(name: Lets.storyboardName, bundle: nil ) let popoverViewController = storyboard.instantiateViewController(withIdentifier: Lets.popoverStoryboardID ) popoverViewController.modalPresentationStyle = .popover guard let popoverPresenter = popoverViewController.popoverPresentationController else { fatalError( "could not retrieve a pointer to the 'popoverPresentationController' property of popoverViewController") } present(popoverViewController, animated: true, completion: nil ) // Retrieve and configure UIPopoverPresentationController // after presentation (per // https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller) popoverPresenter.permittedArrowDirections = .any let button = sender popoverPresenter.sourceView = button popoverPresenter.sourceRect = button.bounds } } 中的代码如下所示:

PopoverViewController

作为弹出窗口呈现的视图控制器是否可以成为其自己的import UIKit // MARK: - main UIViewController subclass class PopoverViewController: UIViewController { // MARK: API var factorForMarginsAroundButton: CGFloat = 1.2 // MARK: outlets and actions @IBOutlet weak var popoverLabel: UILabel! // MARK: lifecycle override func viewWillAppear(_ animated: Bool) { super.viewWillAppear( animated ) // set the preferred size for popover presentations let labelSize = popoverLabel.systemLayoutSizeFitting( UILayoutFittingCompressedSize ) let labelWithMargins = CGSize(width: labelSize.width * factorForMarginsAroundButton, height: labelSize.height * factorForMarginsAroundButton ) preferredContentSize = labelWithMargins // set the delegate for the popoverPresentationController to self popoverPresentationController?.delegate = self } } // MARK: - UIPopoverPresentationControllerDelegate // (inherits from protocol UIAdaptivePresentationControllerDelegate) extension PopoverViewController: UIPopoverPresentationControllerDelegate { func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{ return .none } } 的委托?

我使用Xcode 8.0,Swift 3.1,目标是iOS 10.0

1 个答案:

答案 0 :(得分:1)

这当然是可能的。你正在处理时间问题。您需要在viewWillAppear之前设置委托。不幸的是,没有方便的视图生命周期函数来插入赋值,所以我这样做了。

PopoverViewController课程中,在重写的getter中指定委托。如果您愿意,可以使作业有条件。这会创建一个永久关系,因此其他代码代码永远不会通过分配它来“覆盖”委托。

override var popoverPresentationController: UIPopoverPresentationController? {
    get {
        let ppc = super.popoverPresentationController
        ppc?.delegate = self
        return ppc
    }
}