8

It may be a simple way, but I need some guidance from those who have been familiar with iOS.

If a parent view controller want to send one particular message to all child view controllers, what is the best way?, Still now I have wrote a method in each child view controller and informed whenever necessary, In a situation I want to notify to all childs? What should I do for this? I don't think I need to write the same method in all ViewControllers..

or

Do I need to go for subclassing.... thanks....

Newbee
  • 3,231
  • 7
  • 42
  • 74
  • 1
    You can use delegates... – IronManGill Jun 17 '13 at 09:27
  • If you're talking about parent and child view controllers I would asume you already have been subclassing by definition. – MrBr Jun 17 '13 at 09:29
  • You can also use notifications and add an observer on each object that need to be notified, using `[NSNotificationCenter defaultCenter]` – Alexis C. Jun 17 '13 at 09:29
  • I will second the use of a notification. This decouples the parent and child view controllers. If you want to go down the sub-classing route, do it with interface rather than implementation inheritance by using a protocol. – marko Jun 17 '13 at 09:31
  • check out this link http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers. hope this helps – Singh Jun 17 '13 at 09:38

4 Answers4

10

There are a lot of options for communicating between parent and child view controllers:

  1. Parent -> child

    • Direct interaction: there is an instance in the parent
  2. Child -> parent

    • Delegation [preferred]
    • Notification
    • Pass value via database, Plist file etc.
    • Store in an app delegate instance and pass the value (UIApplicationDelegate)
    • NSUserDefaults

The excellent detailed explanation

Vukašin Manojlović
  • 3,717
  • 3
  • 19
  • 31
Lithu T.V
  • 19,955
  • 12
  • 56
  • 101
  • could you use a weak reference to the parent in this scenario? I know if the child holds a strong reference to the parent it'll create a retain cycle, but what about a weak reference? – MobileMon Apr 01 '15 at 15:01
  • I know this is very old but im still wondering the best approach to this. I would usually use NotificationCenter in this instance but im wondering if there is a better approach to all of this. And for the above comment, there already is a weak reference to the parent controller i believe its just used by calling ```self.parentviewcontroller``` in the child viewcontroller. But then you have to cast it to the actual class name if there is custom functionality you have to use. Which is not a good approach since this child view controller is now hard linked to its parent – Esko918 Feb 10 '16 at 21:59
5

If you simply want to invoke a method on your child view controllers, you could use:

[[self childViewControllers] makeObjectsPerformSelector:@selector(nameOfSelector:) withObject:objectToSend];

or one of the other methods for passing objects along with your selector.

As @Gianluca Tranchedone suggested, you could use delegates or an observer pattern but it really depends on what you need to do and how your code is structured. Making your parent view controller conform to delegates of your child view controllers would allow you to structure your code in a much cleaner way.

Zack Brown
  • 5,990
  • 2
  • 41
  • 54
2

Use the delegation pattern. You specify some methods that you want your delegate to implement as a protocol and have your parent view controller implement the protocol. Your children view controllers can have a property called 'delegate' of type 'id' where MyDelegateProtocol is the protocol you specify. Then, when you want your children view controllers to talk to the parent you can call the methods specified in the protocol. For example, if your protocol specify a method called 'myMethod', in you child view controller you can call [self.delegate myMethod].

Using this approach you can have your children asking information to the parent. If you want to notify children of something that has happened, instead, you better use notifications (NSNotification) or have your children view controllers to observe some property of their parent.

Checkout this guide from Apple called Working With Protocols for more information on how to use them.

Gianluca Tranchedone
  • 3,598
  • 1
  • 18
  • 33
  • Using delegation doesn't help the OP's problem of notifying all child view controllers from the parent. Having each child view controller implementing a protocol would work however. – marko Jun 17 '13 at 09:35
  • You can user observer patten.you can see this question.http://stackoverflow.com/questions/11878265/notify-all-loaded-viewcontrollers-of-a-certain-event – Sonu Jun 17 '13 at 09:42
  • 1
    You can have your children asking information to the parent. If you want to notify children of something that has happened, instead, you better use notifications (NSNotification) or have your children view controllers to observe some property of their parent. I've also updated my answer with the content of this comment. – Gianluca Tranchedone Jun 17 '13 at 09:43
0

You can override prepare segue from a parent view controller and talk to your children like this:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ToServiceController" {
            //ToServiceController is your first child
            secondVC = segue.destination as? ServiceDirectVC
        }else if segue.identifier == "ToMapController" {
            //ToMapController is your second child
            let destVC = segue.destination as! MapVC
            destVC.delegate = self  //This is how you can access your child's local variables
        }
    }

The identifier is defined in your storyboard. Click on the arrows (segues) and look for an identifier tag.

Yash Jain
  • 442
  • 7
  • 19