116

How to add a button to UINavigationBar programmatically?

TheNeil
  • 3,321
  • 2
  • 27
  • 52
RexOnRoids
  • 14,002
  • 33
  • 96
  • 136

7 Answers7

293

Sample code to set the rightbutton on a NavigationBar.

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

But normally you would have a NavigationController, enabling you to write:

UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"
    style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.rightBarButtonItem = rightButton;
Jack
  • 13,571
  • 6
  • 76
  • 98
Mads Mobæk
  • 34,762
  • 20
  • 71
  • 78
  • 1
    I get a warning on the style: parameter -> warning: Semantic Issue: Implicit conversion from enumeration type 'UIBarButtonSystemItem' to different enumeration type 'UIBarButtonItemStyle' – pojo Oct 12 '11 at 20:19
  • 3
    This should be initWithBarButtonSystemItem:UIBarButtonSystemItemDone to avoid the warning. – JordanC Dec 26 '11 at 09:55
  • 2
    In the example, I don't understand where "bar" is coming from. What's the default top bar property for a UINavigationItem ? – aneuryzm Jun 26 '12 at 13:57
  • The bar variable in the answer is any navigation bar that is not managed by a navigation controller. If you have a navigation controller, it has a navigation bar of its own that it manages -- in this case, each view controller that you push to the navigation controller should configure its own navigation item (which includes setting the rightBarButtonItem in its own navigationItem property). – Vasiliy Kulakov Mar 07 '14 at 15:53
  • For current readers, I do not believe there is any reason to call `[rightbutton release]` under ARC (which was not around at the time this comment was originally written). – carbocation May 31 '14 at 15:02
  • @carbocation that's correct. The answer was written before ARC. I have updated the answer and removed the release lines – Mads Mobæk Jun 02 '14 at 13:07
  • @carbocation actually you cannot call release under ARC. So yes, but even moreso ;) – Dan Rosenstark Jun 06 '15 at 22:56
20

The answers above are good, but I'd like to flesh them out with a few more tips:

If you want to modify the title of the back button (the arrow-y looking one at the left of the navigation bar) you MUST do it in the PREVIOUS view controller, not the one for which it will display. It's like saying "hey, if you ever push another view controller on top of this one, call the back button "Back" (or whatever) instead of the default."

If you want to hide the back button during a special state, such as while a UIPickerView is displayed, use self.navigationItem.hidesBackButton = YES; and remember to set it back when you leave the special state.

If you want to display one of the special symbolic buttons, use the form initWithBarButtonSystemItem:target:action with a value like UIBarButtonSystemItemAdd

Remember, the meaning of that symbol is up to you, but be careful of the Human Interface Guidelines. Using UIBarButtonSystemItemAdd to mean deleting an item will probably get your application rejected.

Clafou
  • 15,250
  • 7
  • 58
  • 89
Amagrammer
  • 6,385
  • 3
  • 28
  • 30
11

Adding custom button to navigation bar ( with image for buttonItem and specifying action method (void)openView{} and).

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 32, 32);
[button setImage:[UIImage imageNamed:@"settings_b.png"] forState:UIControlStateNormal];
[button addTarget:self action:@selector(openView) forControlEvents:UIControlEventTouchUpInside];

UIBarButtonItem *barButton=[[UIBarButtonItem alloc] init];
[barButton setCustomView:button];
self.navigationItem.rightBarButtonItem=barButton;

[button release];
[barButton release];
Oleh Kudinov
  • 2,533
  • 28
  • 30
7

The example below will display a button with a title "Contact" on the navigation bar on the right. Its action calls a method named "contact" from the viewcontroller. Without this line the right button is not visible.

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Contact"
                                                                          style:UIBarButtonItemStylePlain target:self action:@selector(contact:)];;

enter image description here

Tibidabo
  • 21,461
  • 5
  • 90
  • 86
3

In Swift 2, you would do:

let rightButton: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightButton

(Not a major change) In Swift 4/5, it will be:

let rightButton: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightButton
Satyam
  • 15,493
  • 31
  • 131
  • 244
Navid Rezaei
  • 1,003
  • 11
  • 22
2

Why not use the following: (from Draw custom Back button on iPhone Navigation Bar)

// Add left
UINavigationItem *previousItem = [[UINavigationItem alloc] initWithTitle:@"Back title"];
UINavigationItem *currentItem = [[UINavigationItem alloc] initWithTitle:@"Main Title"];
[self.navigationController.navigationBar setItems:[NSArray arrayWithObjects:previousItem, currentItem, nil] animated:YES];

// set the delegate to self
[self.navigationController.navigationBar setDelegate:self];
Community
  • 1
  • 1
Joe
  • 208
  • 1
  • 2
  • 7
0

swift 3

    let cancelBarButton = UIBarButtonItem(title: "Cancel", style: .done, target: self, action: #selector(cancelPressed(_:)))
    cancelBarButton.setTitleTextAttributes( [NSFontAttributeName : UIFont.cancelBarButtonFont(),
                                                          NSForegroundColorAttributeName : UIColor.white], for: .normal)
    self.navigationItem.leftBarButtonItem = cancelBarButton


    func cancelPressed(_ sender: UIBarButtonItem ) {
        self.dismiss(animated: true, completion: nil)
    }
venky
  • 1,155
  • 1
  • 11
  • 26