应用程序的某些部分需要使用UINavigationBar + UIToolBar UIAppearance以及半透明的barStyle。

4

我正在使用以下代码为我的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中仅为black translucent barStyle设置自定义图形,而保留其他全部内容?
更新:为了获得一些帮助,我已经编写了一个示例项目,其中使用外观代理无法成功显示带有半透明导航栏的推出视图控制器,并设置了自定义导航栏图形:EXAMPLE PROJECT
2个回答

4
我已经下载了您的示例项目并成功修复了它。我将解释问题所在。
首先,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];
}

在TranslucentViewController中。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

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

哦,只更改这些地方。在推送视图控制器或其他任何操作时不要更改。


0

根据你是否使用选项卡栏,你可以将你的 appDelegate 指定为导航栏的代理,或者子类化 UINavigationController,这样你的代码就能意识到所有 viewController 栈的变化。然后,你可以设置 UINavigationBar 上的属性,使它根据可见 viewController 的类别变成透明或不透明。


我不幸正在使用 UITabBarController - runmad
好吧,情况并不是特别糟糕。tabBarController 成为了 UINavigation bars 的委托,你不能改变这一点。但是,你可以对 UINavigation bar 进行子类化(我出于不同的原因而这样做),并添加方法(也要调用 super!)来拦截对 viewControllers 的更改。这并不难,而且你可以设置 tabBarController 的透明度,因为每个 viewController 都是当前查看的。 - David H
我本以为 UIAppearance 会有处理这个的方法?我的意思是,苹果似乎在 Music.app 中处理得很好。 - runmad
为什么您认为他们是通过UIAppearance实现这个结果的?如果问题仅在从推送PhotoViewer返回时出现,则设置一个标志,当您收到viewWillAppear消息时,请查看该标志,并设置nab栏透明度。或者在viewWillAppear中随处检查它,并根据需要进行设置。 - David H
我已经检查了代码,并在PhotoViewer视图控制器中的viewWillDisappear上将其设置回原始样式。我还尝试在超级视图控制器以及在PhotoViewer之后推送的视图控制器中将其设置为默认值,但都没有起作用。此外,我甚至没有看到默认的黑色半透明样式,而是我的导航栏和工具栏自己的图形,带有一些半透明效果 - 这不是我要寻找的效果。 - runmad

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