TommyG
TommyG

Reputation: 4155

add "done" button to navigation bar without using uinavigationcontroller

I have a view controller that I would like to be able to dismiss with a upper right "done" button on the nav bar. I am not using uinavcontoller, but just added the nav bar like this in my viewDidLoad:

  bar = [[UINavigationBar alloc] init];

in .h:

IBOutlet UINavigationBar *bar;

And of course, connected the nav bar on IB.

Then I tried to add a nav item also within viewDidLoad but nothing happens:

rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonSystemItemDone target:nil action:nil];
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:@"Title"];
item.rightBarButtonItem = rightButton;
item.hidesBackButton = YES;
[bar pushNavigationItem:item animated:NO];

Please note - there are a few questions like that here, but none of them answers this exact question.

thanks for the help!

Upvotes: 1

Views: 12511

Answers (1)

justin
justin

Reputation: 5831

You won't want to alloc/init the bar in your code if you already have it in IB. That will create a second version of it and messages can get skewed. If you are placing the bar into your view in IB, it would be easiest to place your Done button in there as well. First, you'll want to use UINavigationItem instead of UINavigationBar. Drag a UIBarButtonItem onto the right side of your UINavigationItem, change the text from Item to Done, and select the style. Then you will create an IBAction method to do what you want the button to do (dismiss the view). Then it's just a matter of hooking up the selector of your button (in IB) to the IBAction method and that will do what you want.

If you want/need to do this programmatically, you will just use the following.

rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissView:)];
navigationItem.rightBarButtonItem = rightButton;
[rightButton release];

You'll need a dismissView: method, too.

- (IBAction)dismissView:(id)sender {
    // do something;
}

EDIT: to do this all programmatically, you'll start by adding a navigation bar to your header file

UINavigationBar *navBar;

You'll only really need to do this if you plan to allow orientation changes. Since you're not using IB, there's no need to make this an outlet, so we're done in the header.

In the implementation file, you want to call the following:

- (void)viewDidLoad {
    navBar = [[UINavigationBar alloc] init];
    UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:@"some title"] autorelease];
    UIBarButtonItem *done = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissView:)] autorelease];
    navItem.rightBarButtonItem = done;
    navBar.items = [NSArray arrayWithObject:navItem];
    [self.view addSubview:navBar];
}

- (void)viewDidAppear:(BOOL)animated {
    navBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    navBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
}

- (void)dealloc {
    [navBar release];
}

This starts by creating the instances and placing them in your view. Once the view appears and the frame size is known to the program, it resizes the navigation bar (which in turn resizes its subviews) to its proper size. Then any time the orientation changes, it resizes accordingly. I've tested this just to make sure all of it is good info, and it works fine for me, so it should be good for you as well. Hopefully it helps you out

Upvotes: 9

Related Questions