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.
Related
I have 3 buttons in my storyboard and ViewController that are working as expected:
- (IBAction)button0:(id)sender {
[sender setTitle:#"btn0 pressed" forState:UIControlStateNormal];
}
- (IBAction)button1:(id)sender {
[sender setTitle:#"btn1 pressed" forState:UIControlStateNormal];
}
- (IBAction)button2:(id)sender {
[sender setTitle:#"btn2 pressed" forState:UIControlStateNormal];
}
I have a fourth button that, when pressed, I would like to change the displayed text of button0-2 to an empty string.
- (IBAction)resetAllButtons:(id)sender {
//In Android this code would be something like:
//Button btn0 = (Button) findViewById(R.id.button0);
//btn0.setText(" ");
}
How do I do this? I've found many ways to change the button text, but only of the current button being pressed. Can I target all the buttons by id somehow?
Figured it out (although still not clear on why it works?)
I connected button0 as an IBOutlet in my ViewController.h file.
#property (weak, nonatomic) IBOutlet UIButton *button0;
From there I was able to reference it in my ViewController.m file using
[self.button0 setTitle:#" " forState:UIControlStateNormal];
But why am I able to do that? I thought that if I declared
- (IBAction)button0:(id)sender;
in my ViewControler.h file that I couldn't also have an outlet connected to the same object? Thanks for reading either way.
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.
I have a record button, which when pressed, I want to hide the instructions button.
Here's the code for the record button:
// Create custom overlay
// Create instruction/record button
// Add instruction/record button to custom overlay
[_videoRecordBtn addTarget:self action:#selector(startVideoRecord:) forControlEvents:UIControlEventTouchUpInside];
So in startVideoRecord I should have something like:
-(IBAction)startVideoRecord:(id)sender{
[_instru setHidden:YES];
// start recording...
}
But I have no idea how to pass the _instru button over to startVideoRecord.
Add a property to your ViewController to keep a reference to your instructionsButton:
#property (nonatomic, strong) UIButton *instructionsButton;
When you create your instructionsButton, assign it to this property.
Then you can access the button via this property anywhere in your ViewController with self. instructionsButton.
So, your action method would be like:
-(IBAction)startVideoRecord:(id)sender{
self.instructionsButton.hidden = YES;
// start recording...
}
You can do this by 2 way..
1 way - > you set the tag of instructions button.
and use this
-(IBAction)startVideoRecord:(id)sender{
UIButton *instruBtn = (UIButton*)[self.view viewWithTag:your button tag];
instruBtn.hidden = YES;
// start recording...
}
2nd Way - > you make property for your instructions button and use like this
-(IBAction)startVideoRecord:(id)sender{
self.instruBtn.hidden = YES;
// start recording...
}
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
}
I have 2 buttons on my view and i want to disable the first button when i click on an other button and disable the second when I click again on the button.
I have tried with this code
if (button1.enable = NO) {
button2.enable = NO;
}
So I have in a NavigationBar a "+" button and 5 disable buttons in my view.
When I push the "+" button I want to enable the first button and when I push again that enable the second…
Thanks
if (button1.enabled == YES)
{
button1.enabled = NO;
button2.enabled = YES;
}
else (button2.enabled == YES)
{
button2.enabled = NO;
button1.enabled = YES;
}
Is that what your looking for? It would be an IBAction for the other button.
button1.enable = YES should be button1.enable == YES
a better readable form: [button1 isEnabled]
You're saying
if (button1.enabled = NO) {
when you probably mean
if (button1.enabled == NO) {
= is the assignment operator, and == is the boolean equality operator. What you're doing at the moment is assigning YES to button1.enable, which obviously enables button1. Then, because button.enable is true, control enters the if's clause and enables button2.
EDIT: To answer your new question ("When I push the "+" button I want to enable the first button and when I push again that enable the second..."), let's say that you initialise the button states somewhere. In your #interface add an instance variable
NSArray *buttons;
so your interface declaration looks something like
#interface YourViewController: UIViewController {
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
IBOutlet UIButton *button3;
IBOutlet UIButton *button4;
IBOutlet UIButton *button5;
NSArray *buttons;
}
and then initialise buttons like so:
-(void)viewDidLoad {
[super viewDidLoad];
buttons = [NSArray arrayWithObjects: button1, button2, button3, button4, button5, nil];
[buttons retain];
for (UIButton *each in buttons) {
each.enabled = NO;
}
-(void)viewDidUnload {
[buttons release];
[super viewDidUnload];
}
Let's say you hook up the + button's Touch Up Inside event handler to plusPressed:. Then you'd have
-(IBAction)plusPressed: (id) button {
for (UIButton *each in buttons) {
if (!each.enabled) {
each.enabled = YES;
break;
}
}
}
Each time plusPressed: is called, the next button in the array will be enabled. (I'm writing the above away from a compiler; there may be syntax errors.)
You could also make buttons a property. I didn't, because other classes have no business accessing buttons.