It seems the only way to remove a navigation bar with animation is via it sliding upward. I want it to fade, like in Photos.app.
It would be easiest to change the alpha, however Apple's guidelines state:
Prior to iOS v5.0, when used in conjunction with a navigation controller, there are only a handful of direct customizations you can make to the navigation bar. Specifically, it is alright to modify the barStyle, tintColor, and translucent properties, but you must never directly change UIView-level properties such as the frame, bounds, alpha, or hidden properties directly.
The language is a little weird, as it states prior to iOS 5, but it stated you're not allowed to change the alpha value directly, and it never states you're allowed to now.
I don't want my app to get rejected.
How do I fade out the navigation bar like I would the status bar?
How to remove opacity or transparency from sticky navigation/menu bar. If you want to remove the opacity or transparency from the sticky navigation bar, just navigate to Theme Options -> General -> Additional CSS and copy/paste this code and save changes.
A user changes the navigation bar's style, or UIBarStyle , by tapping the “Style” button to the left of the main page. This button opens an action sheet where users can change the background's appearance to default, black-opaque, or black- translucent.
This was a fun one to solve.
It should have been very straight-forward: use UIView transitionWithView
to perform a cross-fade between the hidden and non-hidden states of the navigation bar, as set by the public API setNavigationBarHidden:animated:
. In fact this works for "fading out" the navbar, but fading it back in had an issue. The issue was that the navbar would slide into place regardless of the fact that UIView +transitionWithView:
doesn't animate animatable properties (e.g. frame
) unless you specify UIViewAnimationOptionAllowAnimatedContent
.
To me this says that internally the UINavigationController
repositions the UINavigationBar
inside an animation block regardless of whether animating was specified in the call to setNavigationBarHidden:animated:
. The duration for this animation block is probably set to '0' when animate:
is set to NO
.
The solution is to set the navigation bar visible (sans animation) before the cross-fade transition. This ensures that the navigation bar begins the cross-fade in the correct position, and that the cross-fade will only reveal the new non-hidden state.
My sample project is a standard Single View Application. On the storyboard is a UINavigationController
, which is the entry point. I set the bar style for this controller's UINavigationBar
to black-translucent (similar to the Photos app). The navigation controller's rootViewController
is a simple UIViewController
with a UIImageView
filling the entire bounds (also like the Photos app). I added a UITapGestureRecognizer
on the view to invoke the following code, in the view controller:
- (IBAction) onShowHideNavbar: (id) sender
{
BOOL hide = !self.navigationController.navigationBarHidden;
if ( !hide)
{
[self.navigationController setNavigationBarHidden: hide animated: NO];
}
[UIView transitionWithView: self.navigationController.view
duration: 1
options: UIViewAnimationOptionTransitionCrossDissolve
animations: ^{
[self.navigationController setNavigationBarHidden: hide animated: NO];
}
completion: nil ];
}
All this said, I don't think you'd get into any trouble (Apple Rejection) for messing with the hidden or alpha properties of the UINavigationBar
directly. The docs warn against touching these because they're managed by the UINavigationController and changing them might have unseen consequences. But In My Opinion they're public APIs and as such using them shouldn't be cause for rejection.
You can't animate properties of the navigation bar of a UINavigationController legally.
However, you can show a navigation controller with hidden navigation bar (hiding it always or only on a specific view controller, as you prefer), and replace it with your "special" instance of UINavigationBar
;-)
I attach a sample project (I used an Xcode template to create it faster): FakeNavBar
Look at the viewDidLoad
method of the DetailViewController
:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
self.fakeBar = [[UINavigationBar alloc]initWithFrame:self.navigationController.navigationBar.bounds];
UIBarButtonItem *back = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(back)];
UINavigationItem *backItem = [[UINavigationItem alloc]initWithTitle:@"Back"];
backItem.leftBarButtonItem = back;
[self.fakeBar pushNavigationItem:backItem animated:YES];
[self.view addSubview:self.fakeBar];
}
Here's a video of the final product on YouTube.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With