更新UITabBarController的所有视图控制器

5
我有一个带有四个选项卡的UITabBarController。在每个选项卡所选的视图控制器中,我都有一个重置按钮。点击该按钮将更改所有视图控制器的外观。特别地,它将更改不同视图控制器中某些标签的文本。

是否有一种推荐的方法可以同时更新UITabBarController的所有视图控制器,即使它们重新加载其视图?

我的当前方法是使这些视图控制器符合一个协议。

@protocol XYReloadableViewController
- (void)reloadContents;
@end

当按钮被点击时,向所有视图控制器发送消息-reloadContents

- (IBAction)touchUpInsideResetButton {
    // ...
    NSArray *viewControllers = self.tabBarController.viewControllers;
    for (UIViewController<XYReloadableViewController> *viewController in viewControllers) {
        [viewController reloadContents];
    }
}

然后在每个视图控制器中,我都需要实现该方法:

- (void)reloadContents {
    [self.tableView reloadData];
    // other updates to UI ...
}

但是这似乎有点太复杂了。那么,有没有更简单的方法告诉视图控制器重新加载它们的视图?


编辑:如果我在某些选项卡中呈现了UINavigationController或容器视图控制器,会发生什么情况?我需要将消息传递给所有子视图控制器的链...

2个回答

3
你可以创建 ReloadViewController,让你的所有控制器都继承它。
ReloadViewController 有一个 UIButton 属性和以下方法:
- (void)reloadContents; - (IBAction)touchUpInsideResetButton:(id)sender;
在 .m 文件中:
-(void)viewDidLoad
{
  [super viewDidLoad];
  [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(reloadContents)
                                                 name:@"MyNotification"
                                               object:nil];
}

- (IBAction)touchUpInsideResetButton:(id)sender
{
  [[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotification" 
                                                      object:nil];
}

在您的视图控制器中,只需要重写reloadContents方法即可。

感谢您的代码建议。我想这是对@Nevan答案的很好补充。 - Mischa

2
通知似乎更适合这种情况。当视图控制器需要重置时,请广播一个NSNotification,并让任何可能需要重置自己的视图控制器监听该通知,并触发所需操作。这样,无论它们在导航堆栈中的深度如何,都不会有问题。
您可能希望延迟更新,直到视图实际出现。可以在VC接收到通知时设置一个BOOL needsUpdate,但只在viewWillAppear:中进行实际的更新,以节省资源并防止大量更新同时进行(可能会阻塞主线程)。
如果此行为适用于所有视图控制器,则可以创建一个UIViewController子类,以避免重复编写代码并使它们都继承自该类。或者(如果您正在使用Apple视图控制器子类),则可以创建一个类别,在其中添加通知方法。

感谢您提供这么详细的概念! - Mischa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接