简体   繁体   中英

calling a parent UIViewController method from a child UIViewController

I have a Parent UIViewController, which opens a child UIViewController:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("myChildView") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)

I press a Button in the ChildView which should close the the ChildView and call a method in the Parent View:

self.dismissViewControllerAnimated(true, completion: nil)
CALL PARENTS METHOD  ??????

How to do that ? I found a good answer ( Link to good answer ), but I am not sure if this is the best practice with UIViewControllers. Can someone help ?

One easy way to achieve this you can use NSNotificationCenter for that.

In your ParentViewController add this into viewDidLoad method:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: Selector(("refresh:")), name:NSNotification.Name(rawValue: "refresh"), object: nil)
}

After that add this function in ParentViewController which will get called when you dismiss your ChildViewController :

func refreshList(notification: NSNotification){

    print("parent method is called")
}

and into your ChildViewController add this code where you dismissing your child view:

 @IBAction func btnPressed(sender: AnyObject) {

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "refresh"), object: nil)
    self.dismiss(animated: true, completion: nil)
}

Now when you dismiss child view refreshList method will be call.

Add a weak property to the child view controller that should contain a reference to the parent view controller

class ChildViewController: UIViewController {
weak var parentViewController: UIViewController?
....
}

Then in your code (I'm assuming it's inside your parent view controller),

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("myChildView") as! ChildViewController
vc.parentViewController = self
self.presentViewController(vc, animated: true, completion: nil)

And, as vomako said, call the parent's method before dismissing your child view controller.

parentViewController.someMethod()
self.dismissViewControllerAnimated(true, completion: nil)

Or, you can also call the method in the completion paramter of dismissViewControllerAnimated, where it will be run after you child view controller dismisses:

self.dismissViewControllerAnimated(true) {
    parentViewController.someMethod()
}

Something that I've noticed in your question: Do not call a method (the parent method in your case) after dismissing the view controller. Dismissing the view controller will cause it to be deallocated. Later commands may not be executed.

The link that you've included in your question points to a good answer. In your case, I would use delegation. Call the delegation method in the parent view controller before you dismiss the child view controller.

Here is an excellent tutorial .

protocol SampleProtocol 
{
    func someMethod()
}   


class parentViewController: SampleProtocol 
{
    // Conforming to SampleProtocol
    func someMethod() {
    }
}

 class ChildViewController
    {
        var delegate:SampleProtocol?
    }

    self.dismissViewControllerAnimated(true, completion: nil)
    delegate?.someMethod()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM