Search code examples
iosuitabbarcontrollerreloaddata

Update all view controllers of a UITabBarController


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...


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.