iOS 7 Navigation Bar does not stay clear - ios

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.

Related

Is there a way to change the back button color when using the navigation controller in Xcode [duplicate]

I'm having problems trying to figure out how to change the color of the buttons on the navigation controller.
Previously I had used the following:
[[UIBarButtonItem appearance] setTintColor:[UIColor colorWithRed:226/255.0 green:66/255.0 blue:66/255.0 alpha:0.0]];
and this worked, but I added a new view with a toolbar, and the tool bar button images will not show. If I remove the global coloring, the tool bar items show just fine.
I've tried setting the tint color on both the leftBarButtonItem and the backBarButtonItem in the viewDidLoad method of the view, but both of those properties appear to be null.
I don't want to change the color of the entire navigation bar, just the buttons. Is there a way to do this?
Yeah, I'll just post this as an answer. Your alpha is set to 0. So you're basically saying the same thing as [UIColor clearColor].
Not sure how that ever worked to give you a tint color on your bar button items.
In swift, it can be accomplished by the following command:
if let navController = self.navigationController
{
navController.navigationBar.tintColor = UIColor.whiteColor()
}

How to transition smoothly from translucent to opaque UINavigationBar iOS?

I'm running into problems reconfiguring the UINavigationBar on iOS 7 and 8 when transitioning between views.
My application currently contains the following UIViewController flow:
VC1 --> VC2 --> VC3
In this flow
VC1 is the home screen and has an opaque UINavigationBar
VC2 has a translucent UINavigationBar
VC3 goes back to having an opaque UINavigationBar
The problem I've been running into is that the transitions between these views are all very sloppy looking. To start with I tried the following:
in VC2
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// configure appearance
[self.navigationController.navigationBar configureTranslucentAppearance];
}
And in VC1 and VC3
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// configure appearance
[self.navigationController.navigationBar restoreDefaultAppearance];
}
Here are the implementations of the two helper functions listed above:
- (void)restoreDefaultAppearance {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[self setTitleTextAttributes:#{NSForegroundColorAttributeName: [UIColor JTTextNavBar]}];
[self setTintColor:[UIColor JTTextNavBar]];
[self setBarTintColor:[UIColor JTBackgroundNavBarWithAlpha:1.0]];
[self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self setBackgroundColor:[UIColor JTBackgroundNavBarWithAlpha:1.0]];
[self setShadowImage:[UIImage navigationBarShadowImage]];
[self setTranslucent:NO];
}
- (void)configureTranslucentAppearance {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[self setBackgroundColor:[UIColor clearColor]];
[self setShadowImage:[UIImage new]];
[self setTranslucent:YES];
}
This is the most basic way of handling this transition. It has the following visual artefacts:
When going from VC1 --> VC2 the moment you begin the transition the navigation bar turns black. The animation completes normally
When going from VC2 --> VC1 the nav bar instantly changes to the application default colour before the segue has time to complete.
When going from VC2 --> VC3 the navigation bar instantly goes from translucent to the app nav bar color and then menu items and VC body animate in.
When going from VC3 --> VC2 the nav bar instantly turns black and remains this way until the segue is complete.
None of these transitions look good at all. Ideally I would like the views to transition smoothly along with their new UINavigationBar but the only way I've seen to do this successfully is to manually add a toolbar to each xib.
Any suggestions? Apologies if this description is confusing :(
Edit: Added cropped images of the UINavigationBar and top portion of UIViewController for each of the listed transitions.
I finally found a decent solution!
There doesn't appear to be a proper way to smoothly transition from an opaque to transparent UINavigationBar BUT you can transition smoothly from a view controller with a visible status bar to one that has a hidden status bar.
This opens up a possible workaround which is to add the following in the viewWillAppear of VC2 from above:
[self.navigationController setNavigationBarHidden:YES animated:YES];
Once you have that, manually add a UINavigationBar to your xib and configure it to be transparent (and add all necessary UIBarButtonItem and views).
If everything is hooked up properly transitioning from VC1 to VC2 will hide the UINavigationBar at the same speed as the view transition and VC2 will show up with it's embedded UINavigationBar
Note: To make this work properly you'll have to make sure that in the viewWillAppear of View Controllers that can be accessed from VC2 you reset the UINavigationBar to be visible (if necessary) via:
[self.navigationController setNavigationBarHidden:NO animated:YES];
TL;DR - manually add a UINavigationBar to your transparent nav bar view controller and in its viewWillAppear hide the default one via setNavigationBarHidden:animated:
The black color you're seeing is the background color of the UINavigationController's view. One way to minimize seeing it is to manipulate the background color of that view to the color of the outgoing / incoming view controller's view. This works well if you're working with solid colors. Another approach is to extend your views behind the opaque navigation bar using UIViewController.extendedLayoutIncludesOpaqueBars = YES;
Set the UIWindow background color to your Navigation bar's tintColor.
always use Translucent, plus add an uiview with a color below it and animate it's alpha?
I've struggled with a nearly identical problem. There really aren't any smooth transitions using either a nav bar or toolbar as a blur. The best option that I've found* is to make an image out of the view and then use that image for the transition. Especially if you just need it for transitions, it's just about the cheapest option that still provides a great UI/UX.
*The one caveat is that some of the UI effects in a nav bar and toolbar don't show up when you take a snapshot, screenshot, or rasterize a UIView as an image. This is negligible if used for a transition.
You can create your own navigation bar using just a UIView and that way you have complete control over its appearance, layout, fading etc.
I gave up using UINavigationBar a while ago as it can be a pain to work with, as you are discovering, and now I never ever use it.
I have a root view controller which has a UIView which represents the navigation bar. If I want to do something like add a back button, change the color, show the navigation bar or hide it, change the transparency, etc. that is all controlled by the RVC and other view controllers call methods on the RVC to change the navigation bar depending upon their appearance requirements.
The RVC has a container view which is the full size of the controller view and the other view controllers get loaded into that.
A little bit of configuration to get everything set up, but once done its a structure that can be used in every project that uses a navigation bar very quickly.
So I struggled with this too.
Unfortunately I didn't have any success adding my own navigation bar via the storyboard. Instead, (and I warn you this is hacky) I add a view in the ViewController with the opaque navigation bar that has a negative margin and extends under the navigation bar.
When the ViewController with the transparent navigation bar is pushed the bar then immediately becomes transparent but due to the identically coloured view I have place directly behind it the change isn't noticeable. Et voila.
The code I have is pretty basic and written in C# (Xamarin) but for reasons of completeness....
var backing = new UIView(new CGRect(0, -68, this.View.Frame.Width, 64f));
backing.BackgroundColor = UIColor.Green;
this.View.AddSubview(backing);
Change background color work for me
window?.backgroundColor = Color.red.toUIColor()
I have one more solution..for the ones who are now refactoring the project and cant add navigation bar everywhere.. This is not a perfect solution just like #alexgophermix one. But its not bad either:
let transition = CATransition()
transition.duration = 0.6
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
transition.type = kCATransitionFade
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.layer.add(transition, forKey: nil)
navigationController?.view.backgroundColor = .clear
I am setting my nav bar in viewDidLoad() so this works everywhere and gives a slight different transition. In my case I was setting clear backgrounds somewhere and rest a gradient image. So this small change goes well for everywhere. This transition is not much noticeable but neither looks bad :)
In my case, the black I was seeing was the navbar's background image. Instead of setting it to nil, I set it to match the background color of the view behind the transparent navbar inside viewWillAppear:
let image = UIImage(color: .white)
navigationController?.navigationBar.setBackgroundImage(image, for: .default)
Then, inside willMove and viewWillDisappear I reverted it back to the original color.
YPNavigationBarTransition is a configureable framework animating navigation bars.
YPNavigationBarTransition uses two fake navigationbars (UIToolBar indeed) to simulate bar transitions while making the real navigationbar transparent.
Subclass your own UINavigationController and embed transitioncenter in it like YPNavigationController
Implement YPNavigationBarProtocol for your content controllers respectively.
Done.
A complete demo is include in the repo, checkout it for more details.

Two navigation bar without totally the same color

I have a TabBar with 5 ViewControllers. Each VC has a navigation bar with the same color but 1 of them seems more dark than the other (whatever the color is) even they are all translucent = YES.
It seems to be NO for this one and i dont know why, any ideas?
thanks
self.navigationController.view.backgroundColor = [UIColor whiteColor]; solved it

UINavigationController pushViewController pauses/freezes midway through

I am pushing a view controller via:
[self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
But the animation lags/pauses a for half a second mid way through. The animation is not complete. Here's the gif;
With out more detail I can think of 2 possible problem with that.
Is there Shadow added in code to the view that will be covered by the new ViewController. If it is the case, use ShadowPath or an translucent view instead (the property Shadow is expensive while animating, been there done that)
Is the backgroundColor of new ViewController "clearColor" ? I've seen strange rendering problem with that kind of thing.
Try:
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:vc animated:YES];
That is the 2 possible problems I can think of the top of my head with so few detail.
Never rely on the default background color, it has change with iOS version and is not consistant across controls and can even be different if the view is created in code or from a Xib (in the same iOS version).
In app delegate, set your window's background color to white.
window?.backgroundColor = .white
Also in the the pushed view controller, set its view to white.
view.backgroundColor = .white
I experienced the same issue when programmatically embedding my view controller in a UINavigationController.
While setting the background color as suggested by VinceBurn solved the pausing, it made the entire animation white, fading in the actual content only when the animation finished.
For me the problem was solved by making sure the content was correctly sized in -viewDidLoad.

UINavigationBar appearing as semi-translucent instead of opaque white

This is in an app I'm converting from iOS 6. Initially the ViewController was showing up under iOS 7 with the content of the main view underneath the navigation bar.
In the UI builder view, I turned off "Under Top Bars" and "Under Bottom Bars" in the "Extend Edges" section, to solve that issue. This worked, however, now on this screen the navigation bar appears to be translucent (comes across as grey in the screenshot below).
I've tried explicitly setting "Top Bar" to "Opaque Navigation Bar" under "Simulated Metrics," but this has no effect.
I've tried setting:
self.navigationController.navigationBar.translucent = NO;
in my ViewController's init code, but this also has no effect.
What am I missing?
UPDATE: If I set self.navigationController.navigationBar.translucent = NO; in my first ViewController in the stack, it works. However, prior to the ViewController in question, I do want translucent navbar. It's only when I get to a view several layers deep that I want to have a non-translucent bar (this view has no scrollable data, so it doesn't make sense to have it translucent).
Here's a screenshot of what I'm seeing in the nav bar:
The issue was that I was calling
self.navigationController.navigationBar.translucent = NO;
after my view appeared. I moved that code into my viewWillAppear method, and now it appears correctly:
You can try below code...
self.navigationController.navigationBar.barTintColor = [UIColor redColor];
self.navigationController.navigationBar.translucent = NO;
And Add this code in View viewDidLayoutSubviews function...
You can set it across the board with an app using this:
UINavigationBar.appearance().navigationBarAppearace.translucent = false
I tend to do it in my AppDelegate class when the app initially loads up.
all you need to do for iOS6 is to set the controller's fullscreenlayout to NO and then PUSH it to your NavigationController
[controller setWantsFullScreenLayout:NO];

Resources