Ellands Bloggen

Changing System UIBarButtonItem Type and Behaviour at Runtime

More than once I saw people trying to change the system identifier for UIBarButtonItem programmatically at runtime. Most answers on Stackoverflow will tell you it can’t be done. Technically they’re right. But that’s implementation detail and users don’t care about implementation details, they care about results. They care if your app is easier to use than your competitor’s, that’s for sure. Since I myself had problem finding a good solution I thought it would be nice to share how I did it, and maybe get some feedback on how to do it.

This is how I did it, I wrote a method that recreates the whole button with the correct type. Remember this is ARC-enabled code. So you will need to release the objects manually if you’re not using ARC.

1
2
3
4
5
- (void)setBarButtonTo:(int)type selector:(SEL)selector
{
  UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:type target:self action:selector];
  [self.navigationItem setRightBarButtonItem:add];
}

Then this is how I’m using it:

1
[self setBarButtonTo:UIBarButtonSystemItemAdd selector:@selector(addNewItem)];

This might not be an optimal solution but it works for me, it’s a bit more CPU intensive than it would be to just change the type of the button, but since it’s a system button, it can’t be done. The nice part is keeping localization and accessibility working fine, since those are, as I stated already, system buttons. If you have a better solution I’d love to hear.