Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UINavigationBar:appearance works but not UINavigationBar:appearanceWhenContained in

Tags:

ios

I have a requirement to set the navigation bar to a custom color and this following code will do that:

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

However my application invokes the system MFMailComposeViewController and MFMessageComposeViewController and I want the navigation bar to be the default color for those views, so I did this:

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

However now the navigation bar no longer has my default color. Why is appearanceWhenContainedIn not working?

like image 363
Gruntcakes Avatar asked Aug 07 '12 22:08

Gruntcakes


1 Answers

The argument to appearanceWhenContainedIn: represents a view (and/or view controller) containment hierarchy, not a list of possible containers. (Admittedly, the docs aren't clear on this. See the video from WWDC 2011.) Thus,

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

gives you an appearance proxy for a UINavigationBar contained within a MyViewControllerBase, which in turn is within a MyViewController1 inside a MyViewController2. I'm guessing that's not the containment hierarchy you have.

Instead, look at the view controller which contains your navigation bar. It's probably a generic UINavigationController... but you can't just do

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

because then you'll get the mail/message controllers too. And sadly, while you can get at the appearance proxy for a UINavigationBar within a mail/message view controller, there isn't a way to tell it to undo appearance changes made at a more generic level.

It looks like the usual solution to such scenarios is to make yourself a UINavigationController subclass, and use it for the parts of your UI you want skinned. The subclass can be empty -- it only exists to identify parts of your UI for appearanceWhenContainedIn:. (Meanwhile, things like MFMailComposeViewController continue to use the default appearance because they still use the generic UINavigationController.)

like image 136
rickster Avatar answered Oct 21 '22 19:10

rickster