iOS - How to make a backBarButtonItem also execute a custom function?

6.7k views Asked by At

I am an iOS development newbie. I am using the following code to set my backBarButtonItem -

UIBarButtonItem *temporaryBarButtonItem=[[UIBarButtonItem alloc] init];
temporaryBarButtonItem.title=@"Back";
self.navigationItem.backBarButtonItem = temporaryBarButtonItem;
[temporaryBarButtonItem release];

I also want it to execute another function, apart from going back. Is that possible? Or do I need another button to save?

5

There are 5 answers

0
fearmint On BEST ANSWER

You can practically do that in your viewDidDisappear or viewWillDisappear method.

If this view can only go back and doesn't present any views, then this should work.

However, if you plan on presenting a subview, modal view, go deeper in the navigation hierarchy, or do other view operations that will cause viewDidDisapper to get called, then you'll need to separate your back-button code logic somehow.

For instance if you will present a modal view from this view, you can check if self.modalViewController is nil, if it is then you have no modal view being present and can safely execute the back-button code. If it is not nil then you have a modal view present and should not execute back-button code. (viewWillDisappear should register the modal view controller as not-nil).

0
nswamy On

You can add UIBarButtonItem in xib and add handler event there.

Else create UIBarButtonItem with a custom view, which is an UIButton and add event handler.

1
logancautrell On

Very simple, try this!

    [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(myCoolAction:)];

Then all you do is change myCoolAction: to an appropriate method in your view controller and handle it. Enjoy!

EDIT: Oh, if you want to use this for the backBarButtonItem, it won't work how you expect. The system will not call your target/actions for the backBarButtonItem. They get cleared once assigned to the backBarButtonItem.

One way to handle this is too hook up the your UINavigationController as a delegate. Then in your

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated

Method you can do some custom behavior there.

0
Max MacLeod On

Strictly speaking, this cannot be done with UIKit.

See the docs on backBarButtonItem:

The target and action of the back bar button item you set should be nil. The default value is a bar button item displaying the navigation item’s title.

The work around is to specify a leftBarButtonItem and attach whatever custom behaviour you require by attaching a @selector target.

The tricky bit is the button's image itself. As you know the default is not a rectangular button. Rather it has a left side arrow shape. For this you'll need to set a custom image to make the button appear to be the default.

There's tons of resources to do that out there including this one to extract all the UIKit artwork:

https://github.com/0xced/UIKit-Artwork-Extractor

0
Chris Savory On

You should be able to do something like this instead of using viewDidDisappear or viewWillDisappear.

Place this in viewDidLoad:

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleDone target:self action:@selector(cancelButtonAction:)];
self.navigationItem.leftItemsSupplementBackButton = NO;

Then you can create the method cancelButtonAction cancelButtonAction for your custom code and the back functionality like this:

- (void)cancelButtonAction:(id)sender {
    //Your custom code goes here...


    //This will perform the back functionality if using a Navigation Controller
    [self.navigationController popViewControllerAnimated:YES];
}

Note: this will end up using a rectangular button, without the arrow.