How to have a UIButton image change when a button is touched - objective-c

I'm trying to have the UIButton image change when a button is touched. Currently I it changes but only on the highlighted state change. I would like it to change and stay there. I tried UIControlStateSelected for the state change but no luck.
thanks for the help
here's my code:
// Create buttons for the sliding category menu.
NSMutableArray* buttonArray = [NSMutableArray array];
NSArray * myImages = [NSArray arrayWithObjects:#"category-cafe-unsel.png", #"category-food-unsel.png", #"category-clothing-unsel.png", #"category-health-unsel.png", #"category-tech-unsel_phone.png" , #"category-tech2-unsel.png", #"catefory-theatre-unsel.png", #"category-travel-unsel.png", nil];
NSArray * myImagesSel = [NSArray arrayWithObjects:#"category-cafe-sel.png", #"category-food-sel.png", #"category-clothing-sel.png", #"category-health-sel.png", #"category-tech-sel_phone.png" , #"category-tech2-sel.png", #"catefory-theatre-sel.png", #"category-travel-sel.png", nil];
// only create the amount of buttons based on the image array count
for(int i = 0;i < [myImages count]; i++)
{
// Custom UIButton
btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(0.0f, 20.0f, 52.0f, 52.0f)];
[btn setTitle:[NSString stringWithFormat:#"Button %d", i] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[myImages objectAtIndex:i]] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[myImagesSel objectAtIndex:i]] forState:UIControlStateHighlighted];
NSLog(#"The button title is %# ", btn.titleLabel.text);
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[buttonArray addObject:btn];

In your IBAction method add the following lines:
- (IBAction)change:(id)sender
{
UIButton *button = (UIButton *)sender;
int tagOfButton = button.tag - 1;
[button setImage:[UIImage imageNamed:[myImagesSel objectAtIndex:tagOfButton]] forState:UIControlStateNormal];
}
Add a single line to your for loop like:
for(int i = 0;i < [myImages count]; i++)
{
// other stuffs
btn.tag = i+1;
}
EDIT:
If you need to undone the previous selection when other button is clicked:
write this loop inside your IBAction method.
for(int i = 0;i < [myImages count]; i++)
{
UIButton *but = (UIButton *)[buttonArray objectAtIndex:i];
if(but != button)
{
[btn setImage:[UIImage imageNamed:[myImages objectAtIndex:i]] forState:UIControlStateNormal];
}
}
Or simply store the previous button tag to a variable.
And use it to change undone the image change.

[btn setTitle:#"I'm not selected" forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:[myImages objectAtIndex:i]] forState:UIControlStateNormal];
[btn setTitle:#"I'm selected" forState:UIControlStateSelected];
[btn setImage:[UIImage imageNamed:[myImagesSel objectAtIndex:i]] forState:UIControlStateSelected];
[btn addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)buttonPressed:(id)sender {
btn.selected = !btn.selected;
}

Related

Highlighting the button with sender tag

I have 7 buttons on my storyboard, I have associated a tag number to each of the button. And all the buttons are hooked up to a single IBAction.
In my action method I have a switch statement like switch ([sender tag])
which run the appropriate action according to the tag. This is all working.
But I want to add a functionality where selected button is highlight and rest of them in normal state.
You can create property with tags:
#property (nonatomic, strong) NSArray *tags;
Somewhere (for example, in viewDidLoad) initialize it with values used in storyboard:
tags = #[#1, #2, #3, #4, #5]
And select buttons using this tags
- (IBAction)buttonPressed:(UIButton *)sender {
for (int i = 0; i < tags.count; i++) {
UIButton *button = [self.view viewWithTag:tags[i]];
button.selected = (button.tag == sender.tag);
}
}
Or you can create IBOutlets for every 7 buttons and create array for it.
array = #[outlet1, ..., outlet7]
And select buttons using outlets
- (IBAction)buttonPressed:(UIButton *)sender {
for (int i = 0; i < array.count; i++) {
UIButton *button = array[i];
button.selected = (button.tag == sender.tag);
}
}
Hope this can give you some idea:
- (void)setupButtons {
for (int i = 0; i < 7; i++) {
CGFloat width = self.view.frame.size.width / 7;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(i * width, 100, width, 30)];
[self.view addSubview:button];
button.tag = 1000 + i;
[button setTitle:[NSString stringWithFormat:#"%d", i] forState:UIControlStateNormal];
button.backgroundColor = [UIColor redColor];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];
if (i == 0) {
// default first button selected
button.selected = YES;
}
}
}
- (void)buttonClicked:(UIButton *)sender {
for (int i = 0; i < 7; i++) {
UIButton *button = [self.view viewWithTag:(1000+i)];
button.selected = (button.tag == sender.tag);
}
}

How do I change a button's color when pressed and reset to original color when a different button are pressed?

I have created buttons dynamically based on array count ,if i pressed it will move to next page .i want to change the background color of the button if it is pressed .i pressed 1st button its background color should changed ,and den if i pressed anyother buttons the first pressed button should get into default color of the button , and the new pressed button's background color should changed ,
please help me to do this ,On button clicked method i have tried like this ,
- (IBAction)btn1Tapped:(id)sender {
UIButton *btn = (UIButton *) sender;
selected = YES;
if (selected) {
[btn setBackgroundColor:[UIColor redColor]];
}
}
and this my button creation code ,
int buttonheight = 30;
int horizontalPadding = 20;
int verticalPadding = 20;
int totalwidth = self.view.frame.size.width;
int x = 10;
int y = 150;
for (int i=0; i<array.count; i++)
{
NSString* titre = [array objectAtIndex:i];
CGSize contstrainedSize = CGSizeMake(200, 40);//The maximum width and height
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont systemFontOfSize:20.0], NSFontAttributeName,
nil];
CGRect frame = [titre boundingRectWithSize:contstrainedSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributesDictionary context:nil];
int xpos = x + CGRectGetWidth(frame);
if (xpos > totalwidth) {
y =y +buttonheight+ verticalPadding;
x = 10;
}
UIButton *word= [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.word = word;
NSLog(#"%#", NSStringFromCGRect(frame));
word = [UIButton buttonWithType:UIButtonTypeRoundedRect];
word.frame = CGRectMake(x, y, CGRectGetWidth(frame)+5, CGRectGetHeight(frame));
[word setTitle:titre forState:UIControlStateNormal];
[word setTitle:titre forState:UIControlStateSelected];
word.backgroundColor = [UIColor colorWithRed:30.0/255.0 green:134.0/255.0 blue:255.0/255.0 alpha:1.0];
[word setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[word setTag:i];
[word addTarget:self action:#selector(btn1Tapped:) forControlEvents:UIControlEventTouchUpInside];
word.layer.borderColor = [UIColor blackColor].CGColor;
word.layer.borderWidth = 1.0f;
word.layer.cornerRadius = 5;
[self.view addSubview:word];
x =x+horizontalPadding+CGRectGetWidth(frame);
}
- (IBAction)allBtnSharedTappedevent:(id)sender {
UIButton *btn = (UIButton *) sender;
[btn setBackgroundColor:[UIColor redColor]];
//loop through all your buttons
for(UIView *view in [self.view subviews]){
if([view isKindOfClass:[UIButton class]]){
if(view != btn){
UIButton* btn1 = (UIButton*) view;
[btn1 setBackgroundColor:[UIColor grayColor]];
}
}
}
}
Keep the buttons in an array.
#property (nonatomic, copy, readonly) NSArray<UIButton *> *buttons;
Then in your method that handles the tap, do something like this.
- (IBAction)buttonTapped:(UIButton *)sender {
// Loop through all buttons, clearing the background color
for (UIButton *button in self.buttons) {
button.backgroundColor = [UIColor clearColor];
}
// Set the background color for the selected button
sender.backgroundColor = [UIColor redColor];
}
You should avoid using the tag property of UIView, it will just cause you headaches down the road.
give your button tag number like 1,2,3,4 ... etc
then
- (IBAction)btn1Tapped:(id)sender {
UIButton *btn = (UIButton *) sender;
[btn setBackgroundColor:[UIColor redColor]];
loop through all your buttons
for(int i = 1;i <= total numbers of button; i++){
if(btn.tag != i){
UIButton* btn1 = [myView viewWithTag:i];
[btn1 setBackgroundColor:[UIColor graycolor]];
}
}
}

In Objective-C, how can I make this code efficient?

[self.menuBtn1 setImage:[UIImage imageNamed:#"menu1.png"] forState:UIControlStateNormal];
[self.menuBtn2 setImage:[UIImage imageNamed:#"menu2.png"] forState:UIControlStateNormal];
[self.menuBtn3 setImage:[UIImage imageNamed:#"menu3.png"] forState:UIControlStateNormal];
[self.menuBtn4 setImage:[UIImage imageNamed:#"menu4.png"] forState:UIControlStateNormal];
[self.menuBtn5 setImage:[UIImage imageNamed:#"menu5.png"] forState:UIControlStateNormal];
[self.menuBtn6 setImage:[UIImage imageNamed:#"menu6.png"] forState:UIControlStateNormal];
[self.menuBtn7 setImage:[UIImage imageNamed:#"menu7.png"] forState:UIControlStateNormal];
This Code is very inefficient. But I think it can be efficient with forsyntax. However I don't know how can I code self.menuBtn%d with for. In Objective-C, How can I code this?
This access the button properties dynamically so you don't need an array. This only works if the buttons have already been initialized (they are if they're IBOutlets)
NSString *imageName;
NSString *buttonName;
UIImage *image;
for (int i = 1; i < 8; i++) {
//#autoreleasepool {
imageName = [NSString stringWithFormat:#"menu%d", i];
buttonName = [NSString stringWithFormat:#"menuBtn%d", i];
image = [UIImage imageNamed:imageName];
UIButton *button = (UIButton *)[self valueForKey:buttonName];
if (button)
[button setImage:image forState:UIControlStateNormal];
/*
If you needed to scale this to say 1000 images, you can uncomment the first
and last line in the for-loop which will automatically release the variables
each iteration so the memory consumption doesn't spike.
*/
//}
}
One solution might be to set the tag of all your buttons to some value (e.g. 100 + button number), then to try:
for (UIButton *aButton in self.view.subviews)
{
if ((aButton.tag >= 100 and aButton.tag < 107))
[aButton setImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu%d.png",aButton.tag]] forState:UIControlStateNormal];
}
First add the buttons to the array and the use for loop like this:
NSArray *array=[NSArray arrayWithObjects:menuBtn1,menuBtn2,menuBtn3,menuBtn4,menuBtn5,menuBtn6menuBtn7,nil];
int i=1;
for(UIButton *aButton in array){
[aButton setImage:[UIImage imageNamed:[NSString stringWithFormat:#"menu%d.png",i++]] forState:UIControlStateNormal];
}
NSString *menubutton;
NSMutableArray *imagearray = [[NSMutableArray alloc]initWithObjects:#"image1.png",#"image2.png",#"image3.png", nil];
for(int i=0; i<[imagearray count]; i++)
{
menubutton = [NSString stringWithFormat:#"menuBtn%d",i];
UIButton *button = (UIButton *)[self valueForKey:menubutton];
[button setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#",[imagearray objectAtIndex:i]]] forState:UIControlStateNormal];
}

how to add background color to UIbuttons crested by using for loop based on frame sizes?

I have created 5 buttons using for loop based on incrementing y axis value in CGRectMake. But how can i change the background color of button when i clicked each button?and also title AND having alertview for each button??pls suggest me answer..
//array taken for button titles
NSArray *array1=[NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil];
int k=0;
for(int i=50;i<=350;i=i+70)
{
button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame=CGRectMake(30,i,35,40);
[button addTarget:self action:#selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
if (k<[array1 count])
{
[button setTitle:[array1 objectAtIndex:k] forState:UIControlStateNormal];
}
k++;
[self.view addSubview:button];
}
Try this
-(void) buttonClicked:(id) sender
{
UIButton * button = (UIButton*) sender;
button.backgroundColor = [UIColor yellowcolor];
[button setTitle:#"Hello" forState:UIControlStateNormal];
}
Set the tag for each button and when it's call buttonclicked: is called, then use it's tag rod decide which background color to set it to::
int temptag;
temptag = 0;
for(int i=50;i<=350;i=i+70)
{
button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame=CGRectMake(30,i,35,40);
[button addTarget:self action:#selector(buttonclicked:) forControlEvents:UIControlEventTouchUpInside];
button.tag = temptag;
if (k<[array1 count])
{
  [button setTitle:[array1 objectAtIndex:k] forState:UIControlStateNormal];
  }
k++;  
temptag++;
[self.view addSubview:button];
}
-(void)buttonclicked:(id)sender
{
UIButton *btn = (UIButton *)sender;
switch (btn.tag) {
case 0:
btn.backgroundColor = [UIColor redColor];
break;
case 1:
btn.backgroundColor = [UIColor grayColor];
break;
case ...:
....
default:
break;
}
}

Trouble with "viewWithTag"

oldTag button is not changing back to white ??
What am I missing?
thx
-(void) myCharValue: (UIButton*)btn
{
[btn setBackgroundColor:[UIColor redColor]]; //current tag_button pressed
UIButton *btnTemp;
btnTemp = (UIButton*)[btnChar viewWithTag:oldTag];
[btnTemp setBackgroundColor:[UIColor whiteColor]]; // <--- oldTag button is not changing back to white ??
oldTag = btn.tag;
}
//setup
for (int i=0; i<16; i++) {
for (int j=0; j<16; j++) {
btnChar = [UIButton buttonWithType:UIButtonTypeCustom ];
[btnChar setFrame:CGRectMake(j*40+1, i*40+1, 38, 38)];
[btnChar setBackgroundColor:[UIColor whiteColor]];
[btnChar setTitle:[NSString stringWithFormat:#"%c", k] forState:UIControlStateNormal ];
[btnChar setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnChar addTarget:self action:#selector(myCharValue:) forControlEvents:UIControlEventTouchUpInside];
[btnChar setTag:k];
[svDisplay addSubview:btnChar];
k++;
}
}
I just want to add that the default value of tag property is 0, so if you start your loop with 0, first button will technically not be tagged. Later when you request a viewWithTag: 0 from svDisplay (chech #jrtc27's answer), you will get a first view in that [svDisplay subviews] array.
Your buttons are subviews of svDisplay, not btnChar, so the line btnTemp = (UIButton*)[btnChar viewWithTag:oldTag]; should be btnTemp = (UIButton*)[svDisplay viewWithTag:oldTag];.