Dynamically updating buttons on a view in IOS? - ios

I hope I can ask this question clearly, I have a viewController that I build programmatically (not with NIB), this view controller has two buttons I draw on the lower portion of the view
"prev" and "next" what I'd like to do is, when I've reached the "end" I'd like to only draw the "prev" button, and not the "next", and vice-versa, when I'm at the beginning, I'd like to only draw the "next" and not the prev.
Any general ideas on how to approach this ?
Thanks,
uba

You can use "hidden" property of UIButton:
if (page == firstPage) {
self.myButtonPrev.hidden = YES;
} else {
self.myButtonPrev.hidden = NO;
}
if (page == lastPage) {
self.myButtonNext.hidden = YES;
} else {
self.myButtonNext.hidden = NO;
}

The first thing to do is to addTarget for your button to listen to touch events
[yourButtonNameHere addTarget:self action:#selector(yourCallBackFunctionNameHere:) forControlEvents:UIControlEventTouchUpInside];
What this does is whenever your button is pressed it calls the yourCallBackFunctionNameHere function. Do this for the other button too.
The semi colon after the function indicates that the function has to send the information of the UIElement that caused the event to occur.
Assign tags to both the buttons.
youButtonNameHere.tag=yourTag;
In the function check which button is sending the UIcontrolEvent by comparing the tags
- (void)yourFunctionNameHere:(id)sender {
UIButton *yourButton =(UIButton *)sender;
if(yourButton.tag==501){
// logic to check if this is the first or last page and act accordingly
yourButton.hidden = YES / NO based on what you want to do.
}else{
// logic to do otherwise.
}

Related

a lot of button add same addTarget(_:action:for:) method

I'm working on a calculate app.
and has ton of button which I store in a big stackView (created in SB and no outlet).
each button cast some shadow (also set in SB attribute).
I want to get rid of shadow when button was pressed.
either tapGestureRecognizer or target action could only effect one UIButton.
any convenience way to acheive
PS I mean when button .touchupinside or tapGestureRecognizer .end .start when finger move button should still cast the shadow
help appreciated
UIButton will highlighted on click, so check button setting Change the title color in highlight state config to same as default state Or you can set:
[button setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
If you want to control Highlighted by code, you can disable normal highlighted by subclass Button and disable in touchesBegin:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if (self.state == UIControlStateHighlighted) {
[self setHighlighted:NO];
}
}
You can assign the same IBAction to multiple buttons, so that the same method is called for all of them
func buttonDidTouch(sender:UIButton) {}
If now you want to identify which exactly button is being called, you can use the UIButton.tag property to identify it. The tag can be set in the SB for each button.
There are so many way to achieve the goal but I'm going with below.
Just give my logic.
Take one temporary optional variable of UIButton
Ex.
var myTemButton: UIButton()?
In the button action method
#IBAction func myButtonActionFunc(_ sender: UIButton) {
if myTemButton == nil {
myTemButton = sender
}
else {
// Use "myTemButton" and write here code for remove shadow Or other stuff that you want.
}
// use "sender" and write code here for apply shadow of button or other stuff that you want.
}

UIButton Changes Variable When Tapped?

I have multiple UIButtons - redButton, greenButton, yellowButton, etc. When you tap one of these buttons, another UIImageView will change its image accordingly to, say, redImage, greenImage, yellowImage.
How would I implement this? I've tried this:
[self.redButton addTarget:self action:#selector(changeColour:) forControlEvents:UIControlEventTouchUpInside];
[self.greenButton addTarget:self action:#selector(changeColour:) forControlEvents:UIControlEventTouchUpInside];
[self.yellowButton addTarget:self action:#selector(changeColour:) forControlEvents:UIControlEventTouchUpInside];
And in changeColour:
-(void)changeColour:(id)sender{
// How do I know which button was pressed?
}
All I'd like to know is which button was pressed. Preferrably, I would like it so when a button is tapped, it changes an int variable called colour. So, something like:
if greenButton was tapped, change int = 1. If redButton was tapped, change int = 2.
I've searched StackOverflow and Google and the results say to include a method in the #selector of action:. So what would I have to put in changeColour to recognise which button called changeColour?
-(void)changeColour:(id)sender
{
if (sender == self.redButton) {
// redButton action
} else if (sender == self.greenButton) {
// greenButton action
} else if (sender == self.yellowButton) {
// yellowButton action
}
}
to do these kinds of identification the sender attribute was introduced.
You can use tag property of UIView.
i.e.
self.redButton.tag = 1;
self.yellowButton.tag = 2;
In the chnageColor method, you can retrieve the same.
-(void)changeColour:(id)sender
{
// How do I know which button was pressed?
UIButton *btn = (UIButton *)sender;
if(btn.tag == 1)
//Red is pressed..
//and you can check for other tags...
}
Tap on the UIButton in the Interface Builder, and change the tag property of it in Attributes Inspector. Then access this tag property programmatically in your view controller to get to know which button was pressed.

make button toggle method — objective-c

I have 4 buttons. When they are taped they each create a UIView underneath it, they expand under the buttons. I want the view to go back to its original when the buttons are taped a second time. How is this done?
Set an instance BOOL and flip it accordingly. In the IBAction the button is tied to check the BOOL and call the appropriate method to adjust the view.
You can use the selected property of your button, something like:
-(void)yourButtonIsTapped:(UIButton*)button {
if(button.selected) { //first time
//expand the view
button.selected = NO;
}
else { // second time
//hide view
button.selected = YES;
}
}
You can link the buttons from the IB th this method for the touchUpInside event but you will have to change the return type from void to IBAction.
And I think there are several other solutions for this case but this is the faster one and the easiest to explain.
Set every tag button to 0, change it to the opposite value when you press the button. Here is what you'll get:
First time that you press the button: button's tag = 0, expand the view and turn it to 1.
Second time you press the button: button's tag = 1, collapse it and turn it to 0.
So you haven't to create a bool for every button but you can use your button's tag variable.
Code should be like this.
- (void)handleButton:(UIButton *)button{
if(button.tag == 0) { <expandButton> }
else { <collapseButton> }
button.tag = !button.tag;
}
You can remove a view simply by calling
[viewUnderButton removeFromSuperview];

How to set the UIButton state to be highlighted after pressing it

I have a typical requirement wherein I need to keep a button in highlighted state after pressing it. I need to perform a task which should work only when a button is in highlighted state. Actually I am setting a button state to highlighted programatically.
[sender setHighlighted:YES];
And once the button is in highlighted state i need to perform another action.
- (IBAction)changeState: (UIButton*)sender
{
if (sender.highlighted == YES)
{
[self performSomeAtion:sender];
}
}
But, to my horror, whenever I press any button, the above condition is becoming true and the action is being performed repeatedly. Is there any way in which i can keep a UIButton's state to be highlighted after pressing it?
EDIT - Actually I need to perform 3 different actions for 3 different states of the button. I am already making use of selected state and normal state. Now, I need to make use of the highlighted state.
[sender setSelected:YES];
or you can simulate this effect with two image for your UIButton (notselectedimage.png and selectedimage.png), then keep track button state with a BOOL variable like BOOL buttonCurrentStatus;. Then in .h file:
BOOL buttonCurrentStatus;
and in .m file
// connect this method with Touchupinside function
- (IBAction)changeState:(UIButton*)sender
{
/* if we have multiple buttons, then we can
differentiate them by tag value of button.*/
// But note that you have to set the tag value before use this method.
if([sender tag] == yourButtontag){
if (buttonCurrentStatus == NO)
{
buttonCurrentStatus = YES;
[butt setImage: [UIImage imageNamed:#"selectedImage.png"] forState:UIControlStateNormal];
//[self performSomeAction:sender];
}
else
{
buttonCurrentStatus = NO;
[butt setImage:[UIImage imageNamed:#"notSelectedImage.png"] forState:UIControlStateNormal];
//[self performSomeAction:sender];
}
}
}
- (void)mybutton:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = ![button isSelected]; // Important line
if (button.selected)
{
NSLog(#"Selected");
NSLog(#"%i",button.tag);
}
else
{
NSLog(#"Un Selected");
NSLog(#"%i",button.tag);
}
}
The highlighted state is used to highlight the button while it is being touched. A touch down event in the button highlights it. You should use the "selected" state instead.
If what you want to do is perform an action after the button is pressed, don't attach your method to the state change event, attach your method to the TouchUpInside event.
I just find a way, so I share it, just in case...
I kept my UIButton and set one image for each state (so you could go up to a 4 states button).
I set the UserInteractionEnabled to NO -> This button won't receive any touch.
The purpose of this first button is to show a state
I create a second custom UIButton with the same frame than the first one. For this one, none image will be set for the state (it's a fully transparent button). The purpose of this button is to catch the touch event. So I added a target to this button on the TouchUpInside event. And then when the event is fired, I change the state of the first button to Disabled, Highlighted, Selected, or none of these state (= Default state).
Everything is working like a charm!
The way you describe it, you'd be better off subclassing UIView to create your own three-state button.
Actually, you should even implement your own multistate buttonView, and manage the state it's in internally via an array of PNG for the looks and an array of states to know how many times it's been pressed.
Use [sender setSelected: YES];, I think it will be useful to you.
UIButton *btn_tmp=sender;
if(!(btn_tmp.selected))
{
[btn_temp setHighlighted:YES];
}
For iOS 7 only: you should consider setting the image renderMode to UIImageRenderingModeAlwaysTemplate. You can then use the tintColor to represent various states.
see How to apply a tintColor to a UIImage?
and
see Tint a UIView with all its subviews
The solution is tricky but it's possible.
The problem is that you tried to change the highlighted status in the button action method, which I suppose makes a clean up or check process at the end of the action and switch the highlighted status. When you try to debug it you get the highlighted = 1 but it will change at the end.
Strange but your "3 statuses button" is sometimes useful, when you'd like to keep a button in "highlighted" mode like the "selected" mode to get different action depending on the 3 statuses.
The only problem that you couldn't analyze this or switch it to highlighted mode in the button action method as this will switch to highlighted mode immediately as the user push it AND switch it back at the end.
The solution is using a dispatch.
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[theButton setHighlighted:YES];
});
This will do the trick and you could use the 3 statuses.
According to apple, UIButton has a property of imageView:
Although this property is read-only, its own properties are read/write. Use these properties to configure the appearance and behavior of the button’s view
This means that you can set in the IB (in the storyboard) a picture for this button and set the highlighted picture:
Open the Attribute inspector.
Under Button section, choose an image.
In the same section, change the State Config to Highlighted. Notice the image you chose under default is now gone and now you can set a new picture for the Highlighted.
Now you have a button with 2 state config and all you have to do during runtime to change the button.highlighted = true. Also, check the UIControl under Configuring the Control’s Attributes for more states.
You can also do it programatically as follows:
Swift (and almost the same in Objective-C):
// Setting the highlighted image
self.someButton.imageView?.highlightedImage = UIImage(named: "imageNameFromImageAssest")
// someButton will now some the highlighted image and NOT the image set in the IB
self.someButton.imageView?.highlighted = true

How to use multiple buttons in the same window?

Using XCode 3.2, What I'm trying to do is have the user input data and then they have three choices of what to do with that data, i.e. there are three different options or three buttons that I want to have in the same window. I can't figure out to have that coded...
right now i have one button that is activated using the
-(IBAction)buttonPressed
{ (formula)
}
how do I do this with multiple buttons?
I've looked for answers but they are a bit different than what Im looking for. Thank you so much!
while creating buttons set mybutton.tag=0;like this.change 0 to ur own and compare them in buttonpressed function
use sender to
-(IBAction)buttonPressed:(id)sender
{
UIButton *temp=(UIButton*)sender;
if([temp tag] == 0)
(formula)
//button 0
}
if([temp tag] == 1)
(formula)
button 1
}
}
Button press code should look like this:
- (IBAction)buttonPressed:(id)sender {
UIButton *senderButton = (UIButton *)sender;
if (senderButton == btnOK) {
// this is the OK button
} else if (senderButton == btnCancel) {
// this is the Cancel button
}
}
A better way, though, is probably to write three separate methods, and hook each one up to its corresponding button in IB.

Resources