How can i assign an action to rightbarbuttonitem with an edit style? - ios

I have an edit rightbarbuttonitem in my view in navigation bar. I set it up with the help of storyboard/IB, not programmatically. Now, all i want is to assign an action when the "done" barbuttonitem is pressed (not edit).
Is there a way to achieve it? I tried manually through -(IBAction), but it's not working. Also, i want to perform the action on selected items in UITableView. So if you give me an idea, it would be great.

That button calls the method
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
You can implement it and it will get called everytime your edit/done button gets tapped. All you have to do is check the button's title property to see when it's showing done and when it's showing edit

If you declared your button as an IBOutlet then all you'd need to do is use the synthesised variable on your .m as so:
_yourBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(runMethod)];
self.navigationItem.rightBarButtonItem = _yourBarButton;
Then you'd have to declare your run method:
-(void)runMethod
{
//do stuff
}

Related

UINavigationController – Override Back button action

I have a view controller in a navigation stack that represents a form that the user can fill out. The form has a handful of text fields and an "Apply" button at the bottom. If the user taps the native back button on the navigation bar after entering some information, I want the user to be prompted with a confirmation message: "Your changes have not been saved. Are you sure you want to go back?" But I'm not sure of a way I can "legally" override the action of the native back button. Is this possible?
In Objective C you can override the navigationShouldPopOnBackButton function of the ViewController class to display a prompt message to the user
-(BOOL) navigationShouldPopOnBackButton {
// Do your logic
return NO;
}
You need to set UINavigationItem to the custom button in you UIViewController class.
After that you can execute your custom code in the backButtonTouch: function:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Back", nil)
style:UIBarButtonItemStyleDone
target:self
action:#selector(backButtonTouch:)];

How to assign actions to UINavigationItem backBarButtonItem

I am trying to find a way to stop some of the processes within a detail controller (and let the user know that this is happening) when the back button in the navigation bar is pressed. However, I can't find a way to implement these changes when the button is pressed.
Is there a way to do this?
If you want to raise a user alert/notification before going back, you are really going to have to create your own back bar button item and assign it to self.navigationItem.leftBarButtonItem.
You need to hide the default button using:
self.navigationItem.hidesBackButton = YES;
Then add a target to your new button which does your process cleanup and raises an alert. In the alert handler, pop the controller once the user has acknowledged the alert.
The fastest and easiest way is to use custom back button like below;
-(void)viewDidLoad{
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(actionBack)];
[self.navigationItem setBackBarButtonItem:barButtonItem];
}
-(void)actionBack{
//PopViewController
}
Like any other button.
Put this in the .m file.
- (IBAction)saveButton:(id)sender {
//actions
}
Then control drag from the UINavigationBarButton to the IBAction

iOS - opposite of nil for rightBarButtonItem

I need to make a button reappear after I set it to nil but I can't seem to figure it out.
I set it to nil using:
self.navigationItem.rightBarButtonItem =nil;
When you set the button to nil you destroy (deallocate) it. Just recreate the button. Or, if it's expensive to create for some reason, create another property which holds the button and then use that to restore the rightBarButtonItem.
It's a requirement to set the button to nil? Another approach is to set the button's background alpha to 0, or disable it with setEnabled:NO. If it's a requirement, you have two options:
Store the button as a property and assign the button to the rightBarButtonItem of the navigationItem. Make sure you do all button manipulation to the property.
Create a method to create an instance of UINavigationItem with the button and assign this button to rightBarButtonItem. By the way, if you want to have exactly the same instance you had in the nil assignment, you must use the first option.
Hope it helps!
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done)];
[self.navigationItem setRightBarButtonItem:doneButton animated:YES]
Hide the button by setting the reference to nil, however if you want to restore it later, you'll need to hang onto a copy of it so you can reassign it.
UIBarButtonItem *oldButton = self.navigationItem.rightBarButtonItem;
[oldButton retain];
self.navigationItem.rightBarButtonItem = nil;
//... later
self.navigationItem.rightBarButtonItem = oldButton;
[oldButton release];
Or create a property of the barbuttonitem and just pass it whenever you need it.
#property (nonatomic, retain) UIBarButtonItem *rightNavButton;
self.navigationItem.rightBarButtonItem = self.rightNavButton;

setting action from navigation bar item created programmatically

My storyboard is like this:
So from navigation controller , i am going to a tab controller.
My tab controller has its classed, named: MYTabBarView
In MyTabBarView.m , in its ViewDidLoad method I created the right bar button item programmatically like this:
UIBarButtonItem *homeButton = [[UIBarButtonItem alloc] initWithTitle:#"Home" style:UIBarButtonSystemItemAction target:self action:#selector(homeButtonAction)];
self.navigationItem.rightBarButtonItem=homeButton;
my question is how do I write an action for it. I mean if it was a button that was visible in the storyboard, I would "drag and dropped" it in the .h file and in the .m file I would have
the method:
Now what should I do?
- (IBAction)home:(id)sender {
....
}
Use the selector you typed when you created the button:
- (void)homeButtonAction {
// Code
}
And if you want to pass along the sender use #selector(homeButtonAction:) and the following method:
- (void)homeButtonAction:(id)sender {
// Code
}

How can I determine whether a back button is displayed?

In an iOS app, how can I determine whether a back button is displayed? Ideally, I'd like to know this in my controller's loadView method.
Here's what I've tried in loadView, viewDidLoad, and viewWillAppear:
if (self.navigationItem.backBarButtonItem)
and this:
if (self.navigationItem.leftBarButtonItem)
Neither of those work - they're always nil (the expression evaluates to false), even when there is a back button on the screen. What I'd ultimately like to do is set a Cancel button as the self.navigationItem.leftBarButtonItem, but only if there's no back button. If there is a back button, we don't need the Cancel button. As it is, setting the leftBarButtonItem is overriding the back button, so we're seeing a Cancel button all the time - even when there should be a back button.
You're asking the wrong object for its backBarButtonItem. This property controls how an object is represented when it is the "back" item in the navigation stack.
Therefore, you need to be asking the view controller at the level below where you are in the navigation stack what its backBarButtonItem is:
int n = [self.navigationController.viewControllers count] - 2;
if (n >= 0)
if ([(UIViewController*)[self.navigationController.viewControllers objectAtIndex:n]navigationItem].backBarButtonItem == nil)
// Do your thing....
You may need to check if the navigation controller has added your viewController to the stack at the time you are executing this code, the top view controller may still be the previous one. I've checked in viewWillAppear and the stack does contain the new top controller at this point.
NSLog(#"%#",self.navigationController.navigationBar.backItem);
if (self.navigationController.navigationBar.backItem == NULL) {
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(addLaunch)];
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
}
this code works, its in the viewDidAppear, if your controller is null, theres no button, so i add the cancel button, its not a back item though, just a regular:] hope this helps
loadView is too early. The earliest you could check this is in viewDidLoad. You may need to wait for viewWillAppear.
Search for the following
self.navigationController.navigationBar.backItem
instead of backBarButtonItem.
If backItem exists then you are on navigation stack further than rootViewController.
Just use this code:
if (![[[self.parentViewController childViewControllers] firstObject] isKindOfClass:[self class]]) {
}

Resources