UINavigationBar:外观工作,但不是UINavigationBar:appearanceWhenContained中

我有要求将导航栏设置为自定义颜色,下面的代码将执行此操作:

[[UINavigationBar appearance] setBackgroundImage:navigationBarTileImage forBarMetrics:UIBarMetricsDefault]; 

然而,我的应用程序调用系统MFMailComposeViewController和MFMessageComposeViewController,我希望导航栏作为这些意见的默认颜色,所以我这样做:

 [[UINavigationBar appearanceWhenContainedIn: [MyViewControllerBase class], [MyViewController1 class], [MyViewController2 class], nil] setBackgroundImage:navigationBarTileImage forBarMetrics:UIBarMetricsDefault]; 

但是现在导航栏不再具有我的默认颜色。 为什么外观时不能工作?

appearanceWhenContainedIn:的参数appearanceWhenContainedIn:表示视图(和/或视图控制器)的包含层次结构,而不是可能的容器列表。 (不可否认, 这些文档并不清楚,请参见WWDC 2011的video 。)因此,

 [UINavigationBar appearanceWhenContainedIn:[NSArray arrayWithObjects:[MyViewControllerBase class], [MyViewController1 class], [MyViewController2 class], nil]] 

给你一个包含在一个MyViewControllerBaseUINavigationBar的外观代理,这个MyViewControllerBase又是一个MyViewController1中的一个MyViewController2 。 我猜这不是你拥有的遏制层次结构。

相反,看看包含您的导航栏的视图控制器。 这可能是一个通用的UINavigationController …但你不能这样做

 [UINavigationBar apperanceWhenContainedIn:[NSArray arrayWithObject:[UINavigationController class]]] 

因为那样你也会得到邮件/消息控制器。 可悲的是,虽然你可以在邮件/消息视图控制器中获得UINavigationBar的外观代理,但是没有办法通过它来撤消在更通用的级别上进行的外观更改。

看起来像这样的场景通常的解决scheme是让自己成为一个UINavigationController子类,并使用它的你想要皮肤的部分你的用户界面。 这个子类可以是空的 – 只存在用于标识你的用户界面的部分appearanceWhenContainedIn: whenContainedIn:。 (同时,像MFMailComposeViewController这样的东西继续使用默认外观,因为它们仍然使用通用的UINavigationController 。)

实际上,像@rickster所说的那样,appearanceWhenContainedIn:方法自定义包含在一个容器类的一个实例或一个层次结构中的实例的类的实例的外观。

不是每种情况下你都有一套你想要定制的包含类,但是不同的容器。 能够自定义多个组件的解决scheme只需创build一个需要自定义的类的数组,然后迭代! 像这样:

 NSArray *navigationClass = [NSArray arrayWithObjects:[BSNavigationController class], [DZFormNavigationController class], nil]; for (Class class in navigationClass) { //// Customize all the UINavigationBar background image tilling [[UINavigationBar appearanceWhenContainedIn:class, nil] setBackgroundImage:[UIImage imageNamed:@"yourImage"] forBarMetrics:UIBarMetricsDefault]; [[UINavigationBar appearanceWhenContainedIn:class, nil] setTintColor:[UIColor blackColor]]; // Title Text Attributes NSDictionary *titleAttributes = [NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], UITextAttributeTextColor, [UIColor darkGrayColor], UITextAttributeTextShadowColor, [UIFont boldSystemFontOfSize:20.0], UITextAttributeFont, [NSValue valueWithUIOffset:UIOffsetMake(0, 1)], UITextAttributeTextShadowOffset,nil]; //// Customize all the UINavigationBar title attributes [[UINavigationBar appearanceWhenContainedIn:class, nil] setTitleTextAttributes:titleAttributes]; }