UINavigationBar appearance refresh?
Asked Answered
M

3

22

In my iPad app I have an application settings view. One of the options lets the user switch interface color scheme. The settings view is loaded by segue to a separate view controller than my "main" app's window.

When they pick a new color I switch the colorSchemeColor variable and do this:

// set the colors and refresh the view
[[UINavigationBar appearance] setBarTintColor:colorSchemeColor];
[[UIToolbar appearance] setBarTintColor:colorSchemeColor];
[[UITabBar appearance] setBarTintColor:colorSchemeColor];

However, none of the bars change color until I exit my settings view! (When the settings window disappears, the colors for the "main" app change correctly!)

So then I tried to put this code right after to refresh the settings view:

[self.view setNeedsDisplay];
[self.view setNeedsLayout];

which didn't help. So I added this as well:

[self.navigationController.view setNeedsDisplay];
[self.navigationController.view setNeedsLayout];

This didn't work either.

How can I get my settings view to "redraw" itself when the new color is picked so the change is instantly obvious?

Thanks so much!

Marv answered 8/2, 2014 at 23:12 Comment(0)
I
39

The appearance proxy only affects the look of newly initialized views. Setting colors on the appearance proxy will have no effect on navigation bars that are already visible.

You'll need to manually update your current view; for example:

self.navigationController.navigationBar.barTintColor = [UINavigationBar appearance].barTintColor;
Impignorate answered 8/2, 2014 at 23:17 Comment(1)
I even went one step further. I had a custom tab bar that I also needed to change color of which was instantiated much farther up the parent chain. So to get it referenced, I actually created a delegation protocol and sent the message to the top level navigation controller that way. Once there I used [[UINavigationBar appearance] setBarTintColor:colorSchemeColor]; [[UIToolbar appearance] setBarTintColor:colorSchemeColor]; [[UITabBar appearance] setBarTintColor:colorSchemeColor]; and they reset the colors all the way down through the app.Marv
R
27

Objective-C:

self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;

Swift:

self.navigationController?.isNavigationBarHidden = true
self.navigationController?.isNavigationBarHidden = false
Rodmann answered 7/6, 2016 at 0:5 Comment(4)
Remarkably, this works very well. I am conditionally loading either of 2 view controllers. The second view controller has an edit button at the top. I just could not get that edit button to appear, until I tried this method. The syntax has changed a bit: navigationController?.navigationBarHidden = true navigationController?.navigationBarHidden = falseMc
FWIW, I find that this breaks the navigation bar if it the user is swiping back to previous view controller at the moment of refresh (i.e., swipe from leading edge of screen and hold halfway between view controllers while you trigger the refresh).Impearl
@Rodmann Many thanks. After almost six hours of trying and searching through web this is the only solution that works (and easiest).Aubarta
Brilliant, it might seem counterintuitive, but since .appearance() only affect newly initialised views, this works remarkably well!Eolic
R
11

While I think Aaron Brager's answer is the ideal appraoch, my app needs about 15 different appearance settings and uses a split view controller, so I have to reapply all the setting to the global appearance and then apply them all to my two displayed views. That's a lot of redundant code.

Based on the idea that presenting and dismissing a modal view controller forces everything below it to redraw, I tried this and it worked perfectly:

UIViewController *redrawTrigger = [[UIViewController alloc] init];
redrawTrigger.modalPresentationStyle = UIModalPresentationFullScreen;
[mySplitViewController presentModalViewController:redrawTrigger animated:FALSE];
[mySplitViewController dismissModalViewControllerAnimated:FALSE];
[redrawTrigger release];
Roil answered 1/5, 2014 at 18:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.