UINavigationBar weird color change - cocoa-touch

I am using a custom color for my UINavigationBars that I set globally (on iOS7) in didFinishLaunchingWithOptions:
[[UINavigationBar appearance] setBarTintColor: [UIColor mainThemeColor]];
This works fine, but in two of my screens I see something very odd. When the view appears, I see a dark glow move in from the right, and the color of the bar ends up to be darker than what I set it to. I tried setting the color in viewDidAppear et al, but the same thing happens.
I have no idea how this can happen, all my views and viewControllers are set up the same.
Also, when the app is in the background, and I go to the app switching view (with all the miniature screens), the bar for those two screens is completely dark, instead of the theme color.
Has anyone seen this?
EDIT: It has to do with calling self.edgesForExtendedLayout = UIRectEdgeNone; on my view controllers. If I remove that line, then the coloring of the navbar remains correct. However, in that case, part of my view is hidden.

Related

Navigation bar with coloured translucency over a map

I've a view with nothing but a map on it, inside a navigation controller.
The navigation bar is translucent so the map can be seen slightly through it.
This works fine with the navigation bar tint set to Default, but as soon as I change the bar tint to a specific colour the navigation bar background turns completely transparent.
Interestingly, the issue doesn't happen in the emulator, only on an actual iPhone (a 4 (not S), in case that might be relevant).
I've added no code yet- everything I've put together was generated purely in Interface Builder.
Does anyone have any idea what might be happening here and what I might be doing wrong? Or is this a bug I need to report to Apple?
You need to set the bar's translucent property to true. From the Apple documentation for UINavigationBar:
barTintColor
The tint color to apply to the navigation bar background.
This color is made translucent by default unless you set the translucent property to NO.
When you set a tint color on a UINavigationBar, it sets translucent to false. Unfortunately, translucent can not be set on an appearance proxy. You'll need to add self.navigationController.navigationBar.translucent = YES in all your viewWillAppear: methods (or create your own subclass that changes the default)

iOS 7 multitasking switcher: Navbar appears black

The preview window/multitasking switcher shows a weird behaviour in iOS 7.
Here is how it appears when I set this property for both apps.
self.navigationController.navigationBar.translucent = NO;
Now for the white app I commented the line.
Now when I run it again and go directly to the switcher, this is what I get:
If I run the app and then go to the home screen or any other app and then go to the switcher, this is what I get:
Is there any way to correct this problem while having translucent navbar?
Thanks.
I ran into this as well. Since you don't have any content under the translucent navigation bar (and/or tab bar or tool bar), it can sometimes appear black in the app switcher. I was using a collection view that was constrained to the top and bottom layout guides and so there was nothing behind the tab bar and navigation bar. When the app is in the foreground it looks correct because there must be some default background color applied by Apple (maybe on the UIWindow) so you don't see through to the springboard. This background color seems to be gone (or black) when in the app switcher causing it to look like that.
The problem goes away on view controllers that are set to extend under top and/or bottom bars:
self.edgesForExtendedLayout = UIRectEdgeTop | UIRectEdgeBottom;
or in Interface Builder:
If that doesn't fit you needs or you still have other view controllers that don't extend under top and bottom bars you will still get the black bars in the app switcher. The way I solved it was to set the UIWindow background color in my appDelegate.
self.window.backgroundColor = [UIColor whiteColor];
Instead of doing it in code, you can also do it via Storyboard.
In the navigation bar of your root navigation bar, make sure you turn off its translucency.
I reckon it's a simpler solution.

iOS - UINavigationBar transparent corners not all the time

I'm using a custom UINavigationBar which has transparent corners in the upper left and upper right. I'm using [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navbar.png"] forBarMetrics:UIBarMetricsDefault];
This works great almost all the time but sometimes for instance when I show the keyboard instead of the transparent corners they become white, and when the keyboard slides back the corners go transparent again.
Does anyone have a clue what could cause this? (iOS 6, ARC)
I think I know the cause of it. When I show the keyboard I slide my UITableView up. So I believe it is the UITableViews background that is showing behind the navigation bar. But I would think that the navigation bar wouldn't be affected of that?

How can I adjust UINavigationBar tintColor to compensate for the new gradient effect in iOS6?

In my app I'm tinting the navigation bar to a darker blue color.
The new gradient effects in iOS6 cause the navigation bar to appear much lighter (see below).
If I adjust the color to be darker to compensate for iOS6, it will appear too dark in iOS5.
What's the best way to make them appear the same (or nearly the same)?
Detect the OS version and set different tint colors? Use a background image? Or is there a style setting I can use to change the gradient behavior?
One way you could achieve this is to use a background image and set it using the Appearance proxy introduced in iOS 5.0.
If you create an image that is a thin vertical slice (e.g. width of 1px and height of 44px and the doubled up retina images) and add it to your bundle, then you can then set the navigation bar background image for all navigation bars in your app once using the following method:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navigationBarImage"] forBarMetrics:UIBarMetricsDefault];
If you run that line of code when your app launches, e.g. in the following method of your appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Then every navigationBar in your application will look identical. The advantage of using an image like this is that regardless of OS version and any changes that may or may not come in the future, your application will always look the same.
Just be aware the Appearance proxy API was only added in iOS 5.0, so it wont work with older versions of iOS. For a really good overview of the appearance proxy I'd recommend watching the WWDC 2011 video Session 114.
I had this problem as well, and fixed it by taking out the tint color, and instead doing this:
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
navigationController.navigationBar.backgroundColor = [UIColor blackColor];
Note that this means you'll then have to go change your user interface/xib file, because you changed the style to black translucent - I had to shove everything down 44 points.
Now the navigation bar should look the same in iOS 5 and iOS 6.

XCode Redraw portrait layout with double high status bar

I'm having this issue with several screens in my app, but I'll explain what happens to my home screen. Hopefully the solution isn't as complicated as I'm thinking it will be. So my home screen has a logo at the top, a label(title) under that, 3 horizontal buttons under that, and finally, settings and info buttons in the bottom left and right hand corner respectively when if portrait orientation. In order to allow for landscape orientation, resizing masks were not able to achieve the look I wanted so I implemented the
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
method with an if and else statement, the "if" uses CGRectMakes to draw all of the elements where they should go in landscape layout, and the "else" redraws them back to their original places when changed back to portrait landscape. This all works very nicely. I remembered that we had to be able to handle the double high status bar, so I simulated it to see what it would do to my app. When I am on the home screen and toggle it on and off, the autoresizing of the items(which are set to adjust according to the top of the view) work nicely, by slightly squishing everything down a bit, and not hiding anything. I can toggle it off and on with no problems.
Now here's the problem:
When I have the double high status bar toggled on while on a different screen, then go back to my home screen, the resizing doesn't happen, and it redraws my screen full size according to the coordinates and sizes I have in the method I mentioned earlier, so the settings and info button are drawn halfway off the bottom of the screen. Same happens when switching from landscape back to portrait on the homescreen with the double high status bar already on.
Similarly, I have a map between a nav and tab bar on another page. When already on the page, and toggling it on and off, everything resizes nicely(the frame of the map changes height and the nav bar moves down). But again, I have a problem when switching to that screen from a different screen or from the landscape orientation, because instead of autoresizing appropriately, the map view and nav bar get pushed down behind the tab bar partially, obscuring the google trademark which is grounds for app rejection.
Sorry for the longwindedness, but I wanted to clearly describe what circumstances cause this problem. Any ideas would be greatly appreciated as I don't really have any idea how to approach this.
I've been trying to track down this problem myself. I think this happens because the autoresizing mask is only used when views are resized, and not when a new view is added to the scene.
For me, I wanted a settings view loaded from a nib and added on top of everything else. If the double-height bar was in effect when the view was added it would run off the bottom of the screen. To fix it you have to set the size and position of the view yourself when you load it. This is the code behind my working 'goto settings' button:
- (IBAction) settingsPressed:(id)_sender
{
NSArray* a = [[NSBundle mainBundle] loadNibNamed:#"SettingsView" owner:self options:nil];
SettingsView* settings = [a objectAtIndex:0];
settings.frame = self.view.bounds;
[[self view] addSubview:settings];
}
The important line being:
settings.frame = self.view.bounds;
Which, it would appear, classifies as a 'resize' and so the resizing-mask rules apply. I later added animations for the transition and it continues to work just fine.
Note: This method was in a View Controller.