Calling the uiviewcontroller parent method from the uiviewcontroller child module

I have a parent UIViewController that 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 ChildView, which should close ChildView and call the method in Parent View:

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

How to do it? I found a good answer ( Link to a good answer ), but I'm not sure if this is the best practice with UIViewControllers. Can anyone help?

+6
source share
4 answers

One easy way to achieve this is to use the NSNotificationCenter to do this.

In your ParentViewController add this to the viewDidLoad method:

 override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshList:", name:"refresh", object: nil) } 

After that, add this function to the ParentViewController , which is called when the ChildViewController :

 func refreshList(notification: NSNotification){ println("parent method is called") } 

and in your ChildViewController add this code in which you reject your child's view:

  @IBAction func btnPressed(sender: AnyObject) { NSNotificationCenter.defaultCenter().postNotificationName("refresh", object: nil) self.dismissViewControllerAnimated(true, completion: nil) } 

Now, when you reject the refreshList child view, the method will be called.

+12
source

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

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

Then in your code (I assume it is 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 method before rejecting your child view controller.

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

Or you can also call the method in the completion parameter of the offsetViewControllerAnimated function, where it will be launched after the child view controller rejects:

 self.dismissViewControllerAnimated(true) { parentViewController.someMethod() } 
+2
source

Something I noticed in your question: do not call the method (the parent method in your case) after the view controller is rejected. Disabling the view controller will release it. Later commands may not be executed.

The link that you included in your question indicates a good answer. In your case, I would use a delegation. Call the delegation method in the parent view controller before you release the child view controller.

Here is a great tutorial .

+1
source
 protocol SampleProtocol { func someMethod() } class parentViewController: SampleProtocol { // Conforming to SampleProtocol func someMethod() { } } class ChildViewController { var delegate:SampleProtocol? } self.dismissViewControllerAnimated(true, completion: nil) delegate?.someMethod() 
+1
source

Source: https://habr.com/ru/post/987326/


All Articles