Ruby on Rails, iOS, Git...

We spend a lot of time thinking about these things. If we have something helpful to share, we'll put it here.

Request a free RaddOnline® proposal.

iPhone SDK: UINavigationController, Hiding the Navigation Bar

Posted by Tim Stephenson, RaddOnline® on Friday, April 03, 2009

Hide and Show the Navigation Bar to Maximize the View Area

The navigation bar hides while viewing images in Apple’s Photo app to provide a better view of the image. Hiding the navigation bar is easy. While not exactly the same as the Photo app this technique will hide and show the navigation bar, with an option to animate the transition.

Setup

The method that makes this easy is:

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated

I demonstrate the method in this sample project. To keep it simple, the sample project consists of one view controller, and a single button that toggles the navigation bar between hidden and visible states. This defeats the purpose of a navigation controller, but multiple controllers aren’t required for this demonstration.

hidenavbar-app

Getting Started

  1. In xCode select File => New Project, click on Navigation-Based Application and click Choose.
  2. Name the project and click Save. I named mine HideNavBar.

Next, simplify the Navigation-Based Application template. In most real world applications Apple’s template works well. But there are some situations where I would not want a UITableViewController as the RootViewController. Let’s use a UIViewController instead.

  1. Delete the files RootViewController.h and RootViewController.m. The template added a UITableViewController, and I want to use a UIViewController.
  2. Control click Classes and select Add => New File.
  3. Select UIViewController subclass and click Next.
  4. Name the file, I used RootViewController.m.
  5. Click Finish.

Add an IBOutlet and an IBAction

Open RootViewController.h and add this code:

@interface RootViewController : UIViewController <UINavigationControllerDelegate> {
    IBOutlet UIButton *button;
}

- (IBAction)toggleNavigationBar:(id)sender;

@property (nonatomic, retain) UIButton *button;

@end

Adding an outlet for the button lets you alter the label later. I also added an action to call when the button is clicked. To prevent warnings about the controller not responding to the setNavigationBarHidden:animated: method, I made the controller a UINavigationControllerDelegate.

Change the UI in Interface Builder

The RootViewController is no longer a UITableViewController subclass. Let’s fix the RootViewController.xib file to handle this.

hidenavbar-ibconfig

  1. Open RootViewController.xib.
  2. Delete the TableView.
  3. Add a UIView by dragging it from the library.
  4. Click on File’s Owner, and then click Command + i to bring up the inspector.
  5. Delete the outlet for the TableView. You will see the button outlet, and the toggleNavigationBar action we added.
  6. Double click the View icon to open the view.
  7. Drag a UIButton from the library onto the view and position it.
  8. Double click the button and enter Hide Navigation Bar.
  9. Control click the File’s owner icon and connect the button outlet by dragging from the outlet to the button that was added. Repeat the process to connect the view outlet to the view.
  10. Control click on the button and drag a connection from Touch Up Inside to the File’s Owner. Connect it to the toggleNavigationBar action.
  11. Save and close the file.

Yikes, that seems like a lot of steps. Not to worry, it only takes a minute.

And Now to Make the Navigation Bar Disappear

With all that setup out of the way, let’s get to the interesting part of the show.

Open the HideNavBarAppDelegate.m file and add this to applicationDidFinishLaunching:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

    //Set the navigation bar style to translucent if there is something that you want to show through.
    navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;

    // Configure and show the window
    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];
}

I added a line to set the barStyle to black translucent. If a picture is in the view below, this allows it to show through while the navigation bar is visible.

Open RootViewController.m and complete the implementation.

@synthesize button;

- (IBAction)toggleNavigationBar:(id)sender {
    //Check the current state of the navigation bar...
    BOOL navBarState = [self.navigationController isNavigationBarHidden];
    //Set the navigationBarHidden to the opposite of the current state.
    [self.navigationController setNavigationBarHidden:!navBarState animated:YES];
    //Change the label on the button.
    if (navBarState) {
        [button setTitle:@"Hide Navigation Bar" forState:UIControlStateNormal];
        [button setTitle:@"Hide Navigation Bar" forState:UIControlStateHighlighted];
    } else {
        [button setTitle:@"Show Navigation Bar" forState:UIControlStateNormal];
        [button setTitle:@"Show Navigation Bar" forState:UIControlStateHighlighted];
    }
}

I synthesized the button property and added the toggleNavigationBar method. In the first line I set a boolean to the value returned by the isNavigationBarHidden method. The next line calls the setNavigationBarHidden method using the opposite value of the navBarState variable. This allows the navigation bar to be toggled open or closed based on the state it is in. The last few lines of code change the label on the button.

The last thing I did was to give the controller a title.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Hide Me!";
}

Here’s my test project. HideNavBar.zip

Comments

Huan said on Thursday, July 16, 2009:

Very helful. Thanks! Was looking for that for awhile.
How about if you have a toolbar on the bottom?
How can you hide it on the same time?

I really look for the exact technic as you can see on the photo app! Anyone got a hint?

Marc said on Thursday, January 14, 2010:

any suggestions on how I could make the nav bar hidden at first and the appear after 3 seconds without any touches or buttons being pressed ? - like the photo app but in reverse.

Miguel Campião said on Thursday, January 21, 2010:

Check out NSTimer. You can do something like:

NSTimer * myTimer = [[NSTimer alloc] initWithFireDate:[NSDate date]
interval:2.0 target:self selector:@selector(yourSelectorHere:) userInfo:nil repeats:NO];

Then, on the selector:

-(void)yourSelectorHere:(NSTimer*)theTimer {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35];
[[[self navigationController] navigationBar] setAlpha:0.0];
[UIView commitAnimations];

}

Miguel Campião said on Thursday, January 21, 2010:

Obviously, in my example, the alpha is wrong. To start with the nav bar hidden, you should set the alpha to 0.0 in viewDidLoad. Then, create the timer, with whatever time interval, and inside the selector, should be:

[[[self navigationController] navigationBar] setAlpha:1.0];

in order to make the nav bar visible again.

Gene Myers said on Wednesday, March 31, 2010:

The Apple documentations says: "It is permissible to modify the barStyle or translucent
properties of the navigation bar but you must never change its frame,bounds, or
alpha values directly."

intomo said on Monday, June 28, 2010:

They do this in the NYTimes reader app on iPhone. Both navbar and toolbar fade out.

Paul Michael said on Thursday, October 07, 2010:

Great tip! I will be using this in my next project. Thanks. :)

Mubashir said on Friday, October 22, 2010:

I want to hode the navigation bar when i start editing in the search bar field and unhide when taps cancel button of searchbar

Mubashir said on Friday, October 22, 2010:

I want to hide the navigation bar when i start editing in the search bar field and unhide when taps cancel button of searchbar