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!
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;
Objective-C:
self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;
Swift:
self.navigationController?.isNavigationBarHidden = true
self.navigationController?.isNavigationBarHidden = false
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];
Related
I have a UINavigationController with 3 viewControllers. We know the three viewControllers share a common navigationBar.If I want to set the navigationBar totally transparent. I can put the code in viewWillAppear:
[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setShadowImage:[UIImage new]];
[self.navigationBar setBarTintColor:[UIColor clearColor]];
self.navigationBar.translucent = YES;
and set it back in viewWillDisappear:
[self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self setShadowImage:nil];
[self setBarTintColor:THEME_COLOR];
self.translucent = NO;
I want to set the UINavigationBar translucent only in viewControllerB, so I put the code in viewControllerB. However, when I popToViewController B, I can see a black bar in the top right of the screen. Since the viewWillAppear is invocated. It seems can not be solved in my case.
I come out with some methods:
use different UINavigationBar.
use different UINavigationController. But UINavigationController can not push a new UINavigationController
Custom UIView like UINavigationBar.
I think above methos is more complicated。
Any ideas thanks!
That black color you see is the background color of main window. You can set background image or color to your main window from AppDelegate didFinishLaunchingWithOptions method (That's totally depends with your design of the view controller B) so that you won't see any difference.
Or else
Simply you can use viewDidAppear instead of using viewWillAppear, but that will have little flick though.
I have a question for you about navigation bar transparency.
Here a screenshot of my view:
It's just a UIWebView embedding an HTML page.
I want to make visible the web page under the navigation bar by transparency, but I don't know how to make that.
I've already add self.navigationController.navigationBar.translucent = YES; to the viewDidLoad method, but when I scroll the web page, nothing is visible by transparency.
How I can place the UIWebView frame under the navigation bar, but not the web page ?
Try this
[self.navigationController.navigationBar setBackgroundColor:[UIColor clearColor]];
[self.navigationController.view setBackgroundColor:[UIColor clearColor]];
[self.navigationController.navigationBar setBarTintColor:[UIColor clearColor]];
Do you use your own custom made navigation controller or interface builder? Sometimes I have the same problem with settings in interface builder.
I find how to make that. Just add this in the viewDidLoad method :
self.navigationController.navigationBar.alpha = 0.8f;
self.navigationController.navigationBar.translucent = YES;
I want to have my navigation bar clear in iOS 7. I know this question has been asked before, but I cannot find an answer to the specific problem that I am having. I set my navigation bar clear in my App Delegate using this code:
UINavigationBar *navigationBarAppearance = [UINavigationBar appearance];
navigationBarAppearance.backgroundColor = [UIColor clearColor];
[navigationBarAppearance setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
navigationBarAppearance.shadowImage = [[UIImage alloc] init];
That works fine, my first navigation bar is clear. Then when I select a button and push a new view controller it gets a slight alpha increase on it. Looks like black with about 20% alpha. See picture here:
Then when i press the back button, the first view has the same slight alpha increase affect on it.
I have commented out ALL references to navigation bar in the second view controller to make sure I'm not accidentally changing something. I checked for differences in IB between the first and second view controllers and can't find anything there either. Tearing my hair out!
try setting the translucent property to YES in viewDidAppear
navigationBarAppearance.translucent = YES;
try this !
navigationBarAppearance.layer.backgroundColor = [UIColor clearColor].CGColor;
As expected I was missing something in the code!
The view controller inherited from a custom view controller class that was setting an alpha onto the navigation bar.
I set a certain vertical offset for the navigation bar's title when the app becomes active:
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-3.0f forBarMetrics:UIBarMetricsDefault];
Then, later in the navigation hierarchy, I need to set a different vertical offset, so I call:
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-0.5f forBarMetrics:UIBarMetricsDefault];
But I find that the new vertical offset is not applied when I navigate being the app active. However, if app becomes inactive and then active again, it is applied. How can I change this offset while the app is kept in foreground?
Thanks!
From https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIAppearance_Protocol/index.html
iOS applies appearance changes when a view enters a window, it doesn’t
change the appearance of a view that’s already in a window. To change
the appearance of a view that’s currently in a window, remove the view
from the view hierarchy and then put it back.
So basically you need to do some HACK to remove the view and then immediately add it back, something like this...
UIView *currentview = ((AppDelegate*)[UIApplication sharedApplication].delegate).window.rootViewController.view;
UIView *superview = currentview.superview;
[currentview removeFromSuperview];
[superview addSubview:currentview];
And for Swift...
if let currentview = (UIApplication.sharedApplication().delegate as? AppDelegate)?.window?.rootViewController?.view {
if let superview = currentview.superview {
currentview.removeFromSuperview()
superview.addSubview(currentview)
}
}
Did you try doing this with animation block?
[UIView animateWithDuration:3
animations:^{
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-3.0f forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-0.5f forBarMetrics:UIBarMetricsDefault];
}];
In my app, I use a navigation controller to switch between different views. Each of my views has an image for a background, but when I go from one to another, a little bit of white shows up in between them while transitioning. Is there a way to change that?
In the Table View Class I have this in the viewDidLoad:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"parchment.png"]];
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.backgroundView = imageView;
[imageView release];
In the detail view I have just a standard loadrequest for an HTML. The HTML itself has the code for the parchment paper to be a background image. Here is what they look like:
But, going back from the detail view with the verses to the table view, I get this:
In your:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
method of AppDelegate. assign background color to window like this:
self.window.backgroundColor = [UIColor blackColor]; // or anycolor
Have you tried changing the background color property of the view?
[[self view] setBackgroundColor:[UIColor redColor]];
The issue was in the viewWillDisappear of the web view controller. It was set to change webpage to about:blank page, which made it white. I got rid of that code, and it worked fine.
Try to set the background color of the navigation controller's view.
In your navigation controller's root view controller (I guess it's the table view controller)
self.navigationController.view.backgroundColor = // any color ;