Access the presenting view controller from the pre

2019-04-15 19:44发布

I have a view controller (containing my menu) presented on top of another view controller (my application).

I would need to access the presenting view controller (below my menu) from the presented view controller (my menu), for example to access some variables or make the presenting view controller perform one of its segues.

However, I just can't figure out how to do it. I'm aware of the "presentingViewController" and "presentedViewController" variables but I didn't manage to use them successfully.

Any Idea ?

Code (from the presented VC, which as a reference to the AppDelegate in which the window is referenced) :

if let presentingViewController = self.appDelegate.window?.rootViewController?.presentingViewController {
    presentingViewController.performSegue(withIdentifier: "nameOfMySegue", sender: self)
}

2条回答
ゆ 、 Hurt°
2楼-- · 2019-04-15 20:04

Here is a use of the delegation Design pattern to talk back to the presenting view controller.

First Declare a protocol, that list out all the variables and methods a delegate is expected to respond to.

protocol SomeProtocol {

    var someVariable : String {get set}

    func doSomething()
}

Next : Make your presenting view controller conform to the protocol. Set your presenting VC as the delegate

class MainVC: UIViewController, SomeProtocol {

    var someVariable: String = ""

    func doSomething() {
        // Implementation of do
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Your code goes here.

        if let destVC = segue.destination as? SubVC{
            destVC.delegate = self
        }
    }

}

Finally, when you are ready to call a method on the presenting VC (Delegate).

class SubVC: UIViewController {
    var delegate : SomeProtocol?


    func whenSomeEventHappens() {

        // For eg : When a menu item is selected

        // Set some Variable
        delegate?.someVariable = "Some Value"

        // Call a method on the deleate
        delegate?.doSomething()
    }

}
查看更多
手持菜刀,她持情操
3楼-- · 2019-04-15 20:16

Assuming that VCApplication is presenting VCMenu, in VCMenu you can access VCApplication with:

weak let vcApplication = self.presentingViewController as? VCApplicationType

Your example self.appDelegate.window?.rootViewController?.presentingViewController is looking for the ViewController that presented the rootViewController - it will be nil.

EDIT Per TheAppMentor I've added weak so there are no retain cycles.

查看更多
登录 后发表回答