Two actions for one UIBarButtonItem? - ios

I have an edit button, that I obtained through self.editButtonItem and I have set it as self.navigationItem.leftBarButtonItem, such that when it is pressed, a UITableView begins editing and it turns into a "Done" button. When pressed again the view stops editing and the button returns to its normal state.
I would also like an "add" button to turn into a "Clear" button with a different action linked to it when the edit button is pressed.
(Much like in the iPhone "Phone" app's favourites tab, just that the plus button turns into a clear button when the Edit button is pressed).
I would really like to obtain the edit action and style etc in this way (self.editButtonItem), but I would also like to have an extra selector linked to the edit button.
How should I go about doing this? I have tried to create a category for UIBarButtonItem, but I don't really know what I should do with that.
Thanks.

To create a button whose title can change, you can do the following:
Define an ivar for the button:
UIBarButtonItem *_btnAddClear;
In viewDidLoad:
_btnAddClear = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonItemStyleBordered target:self action:#selector(addClearAction:)];
_btnAddClear.possibleTitles = [NSSet setWithObjects:#"Add", #"Clear", nil];
Since you want this button's title to change when the Edit/Done button is tapped, you can add code like the following:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
_btnAddClear.title = editing ? #"Clear" : #"All";
}
And lastly, the button handler:
- (void)addClearAction:(UIBarButtonItem *)button {
if (self.editing) {
// perform "clear" action
} else {
// perform "add" action
}
}

Give tag of UIBarButton such like 101;
and in BarButton Method write following
-(void)barButtonMethod
{
UIBarButtonItem * myButton = (UIBarButtonItem *) sender;
if(sender.tag == 101)
{
yourBtn.tag = 102;
// Write Your first action method such like
[self ActionMethod1];
}
else
{
yourBtn.tag = 101;
// Write Your second action method such like
[self ActionMethod2];
}
}

You don't really need a new action for the editButtonItem.
There is a property that tracks if the UIViewController is in editing state.
#property(nonatomic, getter=isEditing) BOOL editing
In order to do what you want, you can implement the following method in your UITableViewController:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated]
//Do your thing
}

Related

IOS: How to Reset Action of UIBarButtonItem after it has been created?

I have some code that creates barbuttonitem Edit and if you click it and begin editing, changes the button to Done.
When I first create the button I set its action to Edit. However, once the user is editing, I want to change the action of the renamed button to Save.
I thought I had save firing but somewhere along the line it stopped working possibly when I added a method in the middle to enable and disable the button.
Can anyone suggest the proper way to change the action of a bar button item?
Here is my code:
//code to create button which sets action to gotoEdit method
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStylePlain target:self action:#selector(gotoEdit)];
self.navigationItem.rightBarButtonItem = editButton;
}
-(void) gotoEdit {
self.navigationItem.rightBarButtonItem.title = #"Done";
_editButton.target = self;
_editButton.action = #selector(save);//changes action to save method
//some other code to make a textview editable, change its background color and so forth.
}
-(void) save {
NSLog(#"save method firing");
}
//I added the following methods at about the same time the save method stopped firing but not sure if they are related. (Probably not but including them anyway.)
//detect change on screen
- (void)textViewDidChange:(UITextView *)textView{
self.didChange=YES;
[self updateSaveButton];
}
-(void) updateSaveButton
{
self.editButton.enabled = (_didChange == TRUE);
}
It is better to use a bool instead of adding and removing the button's action.
-(void) gotoEdit {
if(!isEditing){
// Prep for editing
self.navigationItem.rightBarButtonItem.title = #"Done";
isEditing = true;
}else{
// Prep for saving
self.navigationItem.rightBarButtonItem.title = #"Edit";
isEditing = false;
}
}
For future reference you can remove a button's selector like this:
[_editButton removeTarget:self
action:#selector(gotoEdit)
forControlEvents:UIControlEventTouchUpInside];

one Button With Multiple Actions Using StoryBoard in ios

I have three buttons with different actions.Now I don't want to create three IBAction to my buttons.In single IBAction Method can i write the actions for those three buttons.
I am new to Xcode,Can anyone help me to do this...
Thanks in Advance....
try like this
in . h file
#property (strong, nonatomic) IBOutlet UIButton *yourbutton;
in .m
#synthesize yourbutton;
- (IBAction)yourClicked:(id)sender {
UIButton *resultebutton= (UIButton*)sender;
NSString *buttontitle=resultButton.currentTitle;
if ([buttontitle isEqual:#"firstBtitle"]) {
// perform your 1st button action
//call your method
}
else if ([buttontitle isEqual:#"secondBtitle"]) {
// perform your 2nd button action
}
else if ([buttontitle isEqual:#"thirdBtitle"]) {
// perform your 3rd button action
}
}
Assign tag for buttons, and in IBAction method, check Button tag and do action, according to tag of button.
Please correct me, if I get you wrong:
You have three buttons and you want them to trigger the same IBAction. The IBAction itself decides what to do based on which button calls it.
This sounds to me like a perfect example for the "sender" parameter.
Create something like this:
- (IBAction)doSomeAction:(id)sender
{
if ([sender isEqual:self.buttonOne]) {
NSLog(#"ButtonOne");
} else if ([sender isEqual:self.buttonTwo]) {
NSLog(#"ButtonTwo");
} else if ([sender isEqual:self.buttonThree]) {
NSLog(#"ButtonThree");
}
}
With the sender you can identify the button, which calls this method. This way, you can avoid handle tags which can be very annoying to use.
Make sure you connect all three buttons to this action - take a look at the connections inspector. This is very important and a common source for errors. If you remove any connection to an outlet or an IBAction, also check, if this connection ist remove in the Storyboard-object.
If everything is in place just compare the sender with the outlets of the buttons.
Step 1:
Assign your all three buttons different tag in storyboard/XIB,
For ex. firstButton with tag=1, secondButton with tag=2 and thirdButton with tag=3
Step 2:
Define your method like this and bind all your buttons with this method
- (IBAction)buttonAction:(UIButton *)sender
{
if (sender.tag==1) {
NSLog(#"First Button");
} else if (sender.tag==2) {
NSLog(#"Second Button");
} else if (sender.tag==3) {
NSLog(#"Third Button");
}
}
And your work is done.

UITableView --> Editing mode

I have an IBAction with a UIButton that enables the edit mode. I'd like to hit the same UIButton and cancel the edit mode. If I use an if-else statement, what do I check for : if(editeModeEnabled)//turn it off, else turn it on ... so I can use the same UIButton for both on and off.
Thanks much.
You can check for the tableView.editing == YES
eg:
if(self.tableView.editing)
//Turn editing off/save changes
else
{
//Turn editing on
[self.tableView setEditing:YES animated:YES];
}
If the button is a bar button item, then the easiest way to toggle the edit button is to set the bar button item to the pre-configured editButtonItem.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
This special button automatically toggles between "Edit" and "Done"; it also puts the table view in editing mode.

Issues with UINavigationItem changing properties at runtime

i have a Navigation Bar, wich contains a Navigation Item, which contains 2 Bar Buttons, these are created in the Storyboard, and i wanted to change 1 of the buttons at runtime, now this works:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UINavigationItem *thisNavBar = [self myNavigationItem];
thisNavBar.rightBarButtonItem = nil; // this works, it gets removed
UIBarButtonItem *insertBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(insertSkemaItem:)];
thisNavBar.rightBarButtonItem = insertBtn; // this also works, it sets the btn
}
Now, in my other method, which is called by another controller, it does not work
- (void)callChildChange {
...
// remove old btn
UINavigationItem *thisNavBar = [self skemaNavigationItem];
thisNavBar.rightBarButtonItem = nil; // does not work?
}
There is nothing wrong with the method, it runs just fine, but the nav btn item does not get removed ?
skemaNavigationItem is a Navigation item, declared in the .h file which links the navigation item i made via the storyboard.
Your UI items need to be added to your code (by ctrl-dragging) in the header file (.h) so they can be publicly accessed from other classes/view controllers.
Presuming you've done this, hiding a UI item is best done by using
relevantClass.yourViewObject.hidden = YES;
or if you really need to delete it for good,
[relevantClass.yourViewObject.view removeFromSuperView];
Edits
Options for changing target method:
Declare #property (nonatomic, assign) BOOL myButtonWasPressed; and:
- (IBAction) myButtonPressed
{
if (!self.myButtonWasPressed)
{
// This code will run the first time the button is pressed
self.myButton.text = #"New Button Text";
self.myButtonWasPressed = YES;
}
else
{
// This code will run after the first time your button is pressed
// You can even set your BOOL property back, and make it toggleable
}
}
or
- (IBAction) myButtonWasPressedFirstTime
{
// do what you need to when button is pressed then...
self.myButton.text = #"New Button Text";
[self.myButton removeTarget:self action:#selector(myButtonPressedFirstTime) forControlEvents:UIControlEventTouchUpInside];
[self.myButton addTarget:self action:#selector(myButtonPressedAgain) forControlEvents: UIControlEventTouchUpInside];
}
- (IBAction) myButtonWasPressedAgain
{
// this code will run the subsequent times your button is pressed
}

iOS: setting buttons pressed state

I am trying to find the best approach to doing this. I have 5 custom buttons on a view controller and I am trying to have the button stay highlighted if it is clicked. I know how to do this but I am trying to only allow 1 button to be highlighted at a time. So if a user clicks a button and highlights it, but clicks another, then the most recent button clicked will stay highlighted and the previous will unhighlight. What would be the best way to accomplish this?
You should keep a reference to all your buttons (for example, if you use IB, have links in your code like #property (nonatomic, strong) IBOutlet UIButton *button1; for all your buttons).
Then link all your buttons to the same method for a press on the button. I'll call it buttonPressed.
Impement it like this :
- (IBAction)buttonPressed:(id)sender {
UIButton *buttonPressed = (UIButton*)sender;
NSArray *buttons = [NSArray arrayWithObjects:_button1, _button2, _button3, nil];
bool buttonIsHighlighted = NO;
// Check if a button is already highlighted
for (UIButton *button in buttons) {
if (button.highlighted) {
buttonIsHighlighted = YES;
}
}
// If a button is highlighted, un-highlight all except the one pressed
// If no button is highlighted, just highlight the right one
if (buttonIsHighlighted) {
for (UIButton *button in buttons) {
if (buttonPressed == button) {
buttonIsHighlighted = YES;
} else {
button.highlighted = NO;
}
}
} else {
buttonPressed.highlighted = YES;
}
}
I can't test this code but I'm pretty sure it should work. Let me know if something's wrong.
Solution 1:
Put your buttons in an NSArray and when user clicks on a button check if another is highlighted. If YES, unhighlight it and highlight the one was pressed. If NO, highlight directly the one pressed.
Solution 2:
You can save the highlighted button in a global variable declared in #interface or in a #property. When users click the new one unhighlight the previous.

Resources