Update all view controllers of a UITabBarController

ios, reloaddata, uitabbarcontroller

Solution

Notifications sound like a better fit for this. When view controllers need to be reset, broadcast an `NSNotification` and have any view controllers that might need to reset themselves listen for that notification, and trigger what they need to do. That way it doesn't matter how far down a navigation stack they are.

You might want to defer updates until the view actually appears. You could set a `BOOL` `needsUpdate` when the VCs receive the notification, but only do the actual update in `viewWillAppear:`, to save resources and prevent a large number of updates from going off at once (and perhaps blocking the main thread).

If this behaviour is common to all your view controllers, make a `UIViewController` subclass to prevent repeating code and have them all inherit from that. Alternatively, (if you're using Apple VC subclasses) make a category on `UIViewController` to add the notification methods.

Problem

I have a `UITabBarController` with four tabs. In each of the view controllers presented when a tab is selected I have a reset button. Tapping the button will change the appearance of all the view controllers. In particular, it will change the text of some labels in the different view controllers. Is there some recommended way to update all the view controllers of a `UITabBarController` at the same time i.e. to make them reload their views? My current approach is to make those view controllers conform to a protocol ``` @protocol XYReloadableViewController - (void)reloadContents; @end ``` and then send the message `-reloadContents` to all the view controllers when the button is tapped: ``` - (IBAction)touchUpInsideResetButton { // ... NSArray *viewControllers = self.tabBarController.viewControllers; for (UIViewController<XYReloadableViewController> *viewController in viewControllers) { [viewController reloadContents]; } } ``` Then in each of the view controllers I would have to implement that method: ``` - (void)reloadContents { [self.tableView reloadData]; // other updates to UI ... } ``` But that seems a little too complicated. So is there an easier way to tell the view controllers to reload their views? Edit: And what happens if I present a `UINavigationController` in some of the tabs or a container view controller? I would need to pass the message along the chain of all its child view controllers...

Original source