25

I'm a iOS developer with a lot experience in developing the UI by code.

I'm now testing the Storyboard functionality, because I testing to switch to "design" the UI rather then implementing it. In the past I stuck with to much limits using nib/xib's and therefore I never succeed with the switch. So here comes a new try with storyboading :)

Now my question - I'm designing an iPad Storyboard which has a Navigation Controller and a Tableview Controller. I want to add multiple UIBarButtonItems, but I can just add one for each side with the Interface Builder.

The code would look like:

UIBarButtonItem *b = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];

UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
spacer.width = 20;

self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:self.editButtonItem, spacer, b, nil];

But why can't I add multiple buttons using the IB? There are only outlets for leftBarButtonItem, rightBarButtonItems, backBarButtonItems...

This is driving me crazy¡¡¡

Thanks!

user810395
  • 291
  • 1
  • 3
  • 7

6 Answers6

64

I found an easy solution.

1) Add the folowing category:

@interface UINavigationItem(MultipleButtonsAddition)
@property (nonatomic, strong) IBOutletCollection(UIBarButtonItem) NSArray* rightBarButtonItemsCollection;
@property (nonatomic, strong) IBOutletCollection(UIBarButtonItem) NSArray* leftBarButtonItemsCollection;
@end

@implementation UINavigationItem(MultipleButtonsAddition)

- (void) setRightBarButtonItemsCollection:(NSArray *)rightBarButtonItemsCollection {
    self.rightBarButtonItems = [rightBarButtonItemsCollection sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"tag" ascending:YES]]];
}

- (void) setLeftBarButtonItemsCollection:(NSArray *)leftBarButtonItemsCollection {
    self.leftBarButtonItems = [leftBarButtonItemsCollection sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"tag" ascending:YES]]];
}

- (NSArray*) rightBarButtonItemsCollection {
    return self.rightBarButtonItems;
}

- (NSArray*) leftBarButtonItemsCollection {
    return self.leftBarButtonItems;
}

@end

2) Add your items to view controller (items will be sorted ascending by tag)

enter image description here

3) Connect your items with leftBarButtonItemsCollection or rightBarButtonItemsCollection outlet collection of UINavigationItem

enter image description here

Shimanski Artem
  • 1,240
  • 1
  • 11
  • 7
  • 1
    @Shimanski Artem the solution is great! Since I've just started my jurney with iOS could you please explain how does the compiler knows that the Category should be used. What is the mechanism behind? Thanks in advance! – fgeorgiew May 21 '14 at 10:10
  • Couldn't do this via Swift 1.0 but imported fine as objc and works a treat in Xcode 6.0.1. Appreciated! – Tristan Warner-Smith Oct 02 '14 at 13:43
  • Though I failed to finish step 3 in storyboard, I got everything wired up programmatically. – addlistener Oct 20 '14 at 07:45
  • 2
    Brilliant answer. For those having trouble with step 3, select your navigation item that you drag and add to the controller in the storyboard and it will have `rightBarButtonItemsCollection` under it's outlets. Drag from that to the items in your controller to connect them. – CWitty Mar 21 '15 at 18:46
  • Excellent answer. It helped me a lot. I did it in swift. @TristanWarner-Smith In swift adding the collection to the rightBarButtonItems did the trick for me. No objC needed. self.navigationItem.rightBarButtonItems = self.rightBarButtonCollection – hablema Apr 22 '15 at 09:09
  • Even though this is excellent answer, in Xcode 7 it is possible to add multiple UIBarButtonItems directly to the left or right of a IUNavigationItem, which is a much simpler solution. – alcamla Sep 16 '15 at 19:33
26

EDIT

At the time I answered this question, Xcode was not offering the possibility of linking added buttons in the storyboard. The trick presented permitted to still have the segues designed in the storyboard.

With more recent versions of Xcode, for sure the solution introduced by @ecotax and later the more detailed answer of @ShimanskiArtem are the ones to be used.


I had the same problem as you and I found the following trick

Suppose you have a navigationController in which you would like to have multiple buttons. Since iOS 5 you can assign an array. The problem is that you lose all the benefits of using the storyboard as it will be done programmatically.

I used the following trick. Usually when you want multiple button on the navigation bar you don't want a toolbar.

In the current view (not in the navigation controller) where you want the buttons to appear, show the toolbar by changing

bottomBar = inferred to bottomBar = toolbar.

enter image description here

A toolbar will appear at the bottom. Add UIBarButtons to this bar. Link them to other view controllers using segues, etc ...

in your .h file create an outlet for each button

@property (strong, nonatomic) IBOutlet UIBarButtonItem *Button1;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *Button2;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *Button3;

Then in your viewDidLoad() link the buttons to the navigation bar and hide the toolbar. Add them in the reverse order of the order you want to see them

self.navigationItem.rightBarButtonItems =
    [NSArray arrayWithObjects:self.Button3, self.Button2, self.Button1, nil];

self.navigationController.toolbarHidden = YES;

And voilà you have multiple buttons in your navigation bar

enter image description here

enter image description here

and the result in the simulator

enter image description here

enter image description here

idmean
  • 14,540
  • 9
  • 54
  • 83
HpTerm
  • 8,151
  • 12
  • 51
  • 67
  • Thanks for the comment. I struggled a long time finding a workaround. Hopefully in future versions of iOS they will give/add the possibility of directly adding multiple button. – HpTerm Dec 19 '12 at 10:31
  • 3
    One small improvement, IMHO: use an IBOutletCollection instead of multiple IBOutlets. – Eduardo Costa Jul 30 '13 at 14:28
  • See my comment on your answer @EduardoCosta – HpTerm Jul 31 '13 at 06:31
15

I wanted to follow HpTerm's advice, but in my app i do have both a toolbar and a navigation bar.
I found the method outlined in his/her comment can easily be generalized to support this case too. Instead of adding a dummy toolbar, you can simply add the buttons at the same level as the view controller, either by dragging them in the black bar below:

enter image description here

or in the textual overview displayed left:

enter image description here

Assigning the properties to the array in viewDidLoad remains as HpTerm explained; the only difference is there's no dummy toolbar to hide anymore.

ecotax
  • 1,933
  • 17
  • 22
3

In Xcode7, it is possible to add the multiple buttons to UINavigationItem directly in storyboard, without creating an IBOutlet. simply drag multiple UIBarItems to the left or right section of the Navigation item.

Adding Multiple UIBarItems to Navigation Item

alcamla
  • 424
  • 7
  • 12
0

@jchnxu if you havnt already figured out how to finish @Shimanski Artems solution go to story boards and drag a bar button item to the the view controller you have your navigation bar in and drag it on the section where you have the exit and responder icons above the battery icon. From there you can attach them to the collections

kareem
  • 903
  • 1
  • 14
  • 36
0

Man, try this!

self.navigationItem.rightBarButtonItems = @[self.editButtonItem, spacer, b];