UINavigationBar + UIToolBar UIAppearance以及应用程序某些部分的半透明barStyle?

Posted

技术标签:

【中文标题】UINavigationBar + UIToolBar UIAppearance以及应用程序某些部分的半透明barStyle?【英文标题】:UINavigationBar + UIToolBar UIAppearance as well as translucent barStyle in some parts of the app? 【发布时间】:2012-08-27 13:18:59 【问题描述】:

我正在使用以下代码为我的UINavigationBarUIToolbar 设置自定义图像:

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navigationBar"] forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:@"toolbar"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

我正在使用PhotoViewer 并将其视图控制器推入视图。它应该有一个半透明的导航栏和工具栏,但它使用的是我提供的半透明图形。

问题是,稍后当我推入另一个视图控制器时(从 PhotoViewer 弹出回 super 后),它的工具栏也是半透明的,这意味着内容位于它后面。

我没有运气尝试了以下方法:

[[UINavigationBar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBarStyle:UIBarStyleBlackTranslucent];
[[UINavigationBar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBarStyle:UIBarStyleBlackTranslucent];
[[UIToolbar appearanceWhenContainedIn:[EGOPhotoViewController class], nil] setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];

任何想法如何为 PhotoViewer 实现黑色半透明 barStylejust 并使用我的自定义图形保留其他所有内容?

更新:为了获得一些帮助,我将一个示例项目与导航栏的自定义图形放在一起,然后尝试显示一个带有半透明导航栏的推送视图控制器使用外观代理时没有成功:EXAMPLE PROJECT

【问题讨论】:

【参考方案1】:

我已下载您的示例项目并设法修复它。我会解释问题所在。

首先,UINavigationBar 包含在 UINavigationController 中。因此,RootViewController 和 TranslucentViewController 使用相同的 UINavigationBar 实例。也许这会引起混乱。此外,这可能就是 +appearanceWhenContainedIn: 无法按预期工作的原因。

要在整个应用程序中设置导航栏的背景图像,您应该使用 +appearance。要在导航控制器中设置单个导航栏的背景图像,请使用 UINavigationBar 的 -setBackgroundImagE:forBarMetrics:。

代码:在-TranslucentViewController viewWillAppear:设置背景图片和条形样式。在 RootViewController 中,再次设置背景图片和条形样式。根据我的经验,最好在 -viewWillAppear: 而不是 -in viewWillDisappear: 中更改导航栏(或者您需要跟踪将其更改回的内容。)

在 RootViewController 中

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"orangeNavigationBar.png"] forBarMetrics:UIBarMetricsDefault];

在半透明视图控制器中

- (void)viewWillAppear:(BOOL)animated 
[super viewWillAppear:animated];

    [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setBarStyle:UIBarStyleBlackTranslucent];

哦,而且:只在这些地方改变它。不是在推送视图控制器或其他任何东西时。

【讨论】:

【参考方案2】:

根据您是否也使用标签栏,您可以将您的 appDelegate 指定为导航栏的委托,或 UINavigationController 的子类,这样您的代码就会知道对 viewController 堆栈的所有更改。然后,根据可见 viewController 的类设置 UINavigationBar 上的属性以使其透明或不透明。

【讨论】:

不幸的是,我正在使用UITabBarController 嗯,还不错。 tabBarController 成为 UINavigation 栏的代表,您无法更改它。但是您可以继承 UINavigation bar(我出于不同的原因这样做),并添加方法(也称为 super!)来拦截对 viewControllers 的更改。这并不难,您可以根据需要设置 tabBarController 的透明度,因为每个 viewController 都是当前查看的。 我认为 UIAppearance 肯定有办法解决这个问题?我的意思是,Apple 似乎在 Music.app 中做得很好。 你为什么认为他们是通过 UIAppearance 实现这个结果的?如果问题仅在您从推送 PhotoViewer 回来时设置一个标志,当您收到 viewWillAppear 消息时,查看该标志并设置导航栏半透明。或者只是在 viewWillAppear 中的任何地方检查它并根据需要进行设置。 我检查了代码,并在 PhotoViewer 视图控制器中将其设置回 viewWillDisappear 上的原始样式。我还尝试在超级视图控制器以及我在 PhotoViewer 之后推送的视图控制器上将其设置为默认值,但它不起作用。此外,我什至没有看到 default 黑色半透明样式,而是我自己的导航栏和工具栏图形具有一些半透明 - 这不是我想要的效果。

以上是关于UINavigationBar + UIToolBar UIAppearance以及应用程序某些部分的半透明barStyle?的主要内容,如果未能解决你的问题,请参考以下文章

UINavigationBar

UITableView 滚动 UINavigationBar

UINavigationBar 一个有样式的view

UINavigationController改变UINavigationBar导航条标题颜色跟字体

UIBarButton 未在 UINavigationBar 中显示

`UINavigationBar` 弯曲扩展?