使用 UIAppearance 在更改后更新导航栏

Posted

技术标签:

【中文标题】使用 UIAppearance 在更改后更新导航栏【英文标题】:Updating navigation bar after a change using UIAppearance 【发布时间】:2013-02-22 12:14:46 【问题描述】:

我目前正在使用 UIAppearance 代理自定义我的 ios 应用的导航栏背景图像。有一个用于在触发通知的两种不同模式之间切换的按钮。此通知将再次使用代理将背景更改为不同的图像。我的问题是,只有当我转到另一个控制器并返回它时,这种变化才会变得可见。我无法强制更新控制器内的导航栏。

我已经在我的 MainTabBarController 中尝试过这个:

- (void) onAppChangedMode: (NSNotification*)notif 

APP_MODE mode = (APP_MODE) [[notif object] integerValue];

// change navigation bar appearance
[[UILabel appearance] setHighlightedTextColor:[UIColor redColor]];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:(mode == 0 ? @"navbar.png" : @"navbar2.png")] forBarMetrics:UIBarMetricsDefault];
// trying to update
for (UIViewController* vc in self.viewControllers) 
     [vc.navigationController.navigationBar setNeedsDisplay];



但是什么都没有……它不起作用。知道如何实现吗?

谢谢!

【问题讨论】:

我不知道为什么,但是在运行时对 uiappearance 的更改将不适用于任何加载的视图。但是,您可以立即将更改应用于加载的视图本身。 这是否意味着我不能使用 UIAppearance 但我必须单独设置每个栏 没有。您可以使用 UIAppearance 但显示的视图不会受到影响。因此,您应该明确设置一个显示栏。 不知道是不是bug 我不这么认为。 UIAppearance 是一种指定整个应用外观的便捷方式,该任务通常在应用启动时完成一次。 【参考方案1】:

只需从窗口中删除视图并重新添加它们:

for (UIWindow *window in [UIApplication sharedApplication].windows) 
    for (UIView *view in window.subviews) 
        [view removeFromSuperview];
        [window addSubview:view];
    

【讨论】:

这非常适合我。它似乎没有任何性能问题,并且立即生效。【参考方案2】:

我也遇到了同样的问题,这段代码可以帮到你:

- (IBAction)btnTouched:(id)sender 
    [[UADSwitch appearance]setOnTintColor:[UIColor redColor]];

    // Present a temp UIViewController 
    UIViewController *vc = [[UIViewController alloc]init];
    [self presentViewController:vc animated:NO completion:nil];//"self" is an instance of UIViewController
    [vc dismissViewControllerAnimated:NO completion:nil];

【讨论】:

+1 使用了你的方法,我的UITabBarController 收到了警告/问题:Warning: Attempt to present <UIViewController: 0x83ea6e0> on <MNCalendarsTabBarControllerViewController: 0x86861a0> whose view is not in the window hierarchy!。因此,我修改了您的解决方案,将self 替换为UIViewController *presentingController = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; [presentingController presentViewController: viewController animated: YES completion: nil];,发现here - 它有效。坦克,花了我几个小时。【参考方案3】:

尝试使用此代码更改仅当前导航栏的背景图片:

[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];

更改 UIAppearance 后使用上述代码。这将强制更改当前控制器的导航栏。其他控制器的导航栏将由 UIAppearance 的更改来处理。

【讨论】:

编辑了我的答案。将上面的代码与您的代码一起使用以更改 UIAppearance。

以上是关于使用 UIAppearance 在更改后更新导航栏的主要内容,如果未能解决你的问题,请参考以下文章

UIAppearance - 放置的正确位置

为啥我的 Vue 导航栏更改了路由但没有更新路由器视图?

滚动后更改导航栏颜色?

除了在模态视图控制器中使用 UIAppearance 样式吗?

在 iOS 7 中更新导航栏而不更改视图

更改导航栏背景颜色后,self.view 的 y 位置发生更改