mcfly soft
mcfly soft

Reputation: 11645

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 ?

Upvotes: 8

Views: 13122

Answers (4)

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71854

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.

Upvotes: 14

chrisamanse
chrisamanse

Reputation: 4319

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

Upvotes: 5

Nischal Hada
Nischal Hada

Reputation: 3288

protocol SampleProtocol 
{
    func someMethod()
}   


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

 class ChildViewController
    {
        var delegate:SampleProtocol?
    }

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

Upvotes: 1

John
John

Reputation: 8548

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.

Upvotes: 1

Related Questions