UIButton does not change background on touchUpInside - ios

I have some custom type UIButtons placed pragmatically in a custom view. The view is basically a menu. I am generating the buttons with the following code, inside the view's .m file:
-(void) generateButtons: (NSMutableArray *) buttonsArray
{
UIImage *barItemImage = [[UIImage imageNamed:#"ipad-menubar-button.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
float buttonWidth = (self.frame.size.width - (2 * FIRSTBUTTONXCOORDINATE) - 25)/ 6.0f;
float xCoord = FIRSTBUTTONXCOORDINATE;
float yCoord = (self.frame.size.height - BUTTONHEIGHT) / 2.0f;
for (int i = 0; i < buttonsArray.count; i++)
{
NSString* buttonTitle = [buttonsArray objectAtIndex:i];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(botButtonAction:)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:buttonTitle forState:UIControlStateNormal];
button.frame = CGRectMake(xCoord, yCoord, buttonWidth, BUTTONHEIGHT);
button.tag = i;
[button setBackgroundImage:barItemImage forState:UIControlStateNormal];
xCoord += buttonWidth + 5;
[self addSubview:button];
}
}
On touchUpInside, botButtonAction is called and it does what it is supposed to. However, the buttons do not usually give any visual indication of the touchUpInside. When I touchDown on a button and swipe in any direction, then I see the background color get darker. Sometimes, I see the same visual indication on touchUpInside. It seems completely random though.
Any ideas as to what I might be doing wrong here?
Edit: Sorry, I got occupied with other issues. Here is the code for botButtonAction and the method it calls
-(void) botButtonAction: (UIButton *) sender
{
if (self.delegate)
[self.delegate optionsMenuAction:self data:sender.tag];
}
-(void)optionsMenuAction:(OptionsMenueView *)view data:(int)tag
{
if (self.PDFVC)
{
[self.navigationController popToViewController:self animated:YES];
}
if (!self.optionsMenue.isAtWPC || tag != WPC)
[self transitionFromViewAtIndex:self.selectedVCIndex toView:tag];
else
[self transitionFromViewAtIndex:self.selectedVCIndex toView:WPList];
}
But since I am using touchUpInside, these methods don't get called on touchDown. I just want the button to be highLight (grayout the bg a little) on touchDown. As I state before, that happens on touchDown and swipe.
Edit
I had so far been running this on actual devices (iPad air and iPad 2). When I tried running it on the simulator, I get the correct result. On mouse click, the button gets highlighted.
Edit
I think I figured out the exact problem (still looking for a solution). If I touchDown precisely on the button and the touch does not cover any part of the insets, then the highlighting works. However, if the touch covers part of the button and also part of the insets/outside, then the highlighting doesn't work.

add this line:
[button setBackgroundImage:HighlightImage forState:UIControlStateHighlighted];

change the title colour when tap on the button like this
[yourButon setTitleColor:[UIColor colorYouWant] forState:UIControlStateHighlighted];
hope this will help you......

put this code in botButtonAction:
-(void)botButtonAction:(UIButton *)sender
{
[sender setBackgroundImage:[UIImage imageNamed:#"some iamge.png"]
forState:UIControlStateNormal];
}
or use the code below code in for loop
[button setBackgroundImage:[UIImage imageNamed:#"back_button_press.png"] forState: UIControlStateHighlighted];
or if you want to give some color then setcolour of button

I had this problem at some point too. These other answers will give you the result you seek normally. However.... You are using [UIButton buttonWithType:UIButtonTypeCustom].. Which is really buggy if you do not alloc/init the UIButton.. Try changing this line to a normal button allocation and then add the following lines of the answers in this post. This should work for you.
So in short,
replace [UIButton buttonWithType:UIButtonTypeCustom];
with [[UIButton alloc] init];
And then add the following changes to your code to change the image.
[myNewlyAllocatedButton setBackgroundImage:[UIImage imageNamed:#"back_button_press.png"] forState: UIControlStateHighlighted];

Related

Height and Width of the UIbutton on a cell changes on Click

I have 2 questions here.
1.)
In my cellForRowAtIndexPath i have added the following code.
[cell.comB addTarget:self action:#selector(comBClick:) forControlEvents:UIControlEventTouchUpInside];
When the user clicks on the button in that cell the following method gets fired. However, the position of the UIbutton after clicking changes. The button slips down a bit. How can i prevent this ? When i debugged i noticed that the button position changes after executing [((UIButton *)sender) setBackgroundImage:[UIImage imageNamed:#"m.png"] forState:UIControlStateSelected];
line.
- (void) comBClick:(id) sender {
if(c%2==0)
{
[((UIButton *)sender) setBackgroundImage:[UIImage imageNamed:#"m.png"] forState:UIControlStateNormal];
} else {
[((UIButton *)sender) setBackgroundImage:[UIImage imageNamed:#"n.png"] forState:UIControlStateNormal];
}
c=c+1;
}
2.
How can i find the width and height of a UIButton ?
UPDATE
I have got the following AutoLayout Warning, which i believe is the reason for the issue. Can someone tell me what's wrong and how to solve it ?
2)
This is the easiest way:
float widht = ((UIButton *)sender).bounds.size.width;
float height = ((UIButton *)sender).bounds.size.height

Change properties of programmatically created UIButton in a different IBAction

I have one method that creates a number of UIButton instances programmatically and positions them in the view. Another IBAction needs to change the background colour of one of these UIButton when fired however when I try to action it, it tells me that the Property not found on object of type UIView *
The button is created using:
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[view addSubview:button];
When I try to access it from the other IBAction like:
button.backgroundColor = [UIColor blackColor];
It fails with the error noted above.
Any help is much appreciated. I saw another answer which suggested to create an array as an IBOutlet and access it that way but I'm wondering if there's another way.
Thanks!
declare this button in globally and identify each button in tag, just like or assume this
UIButton * button, *button2; // declare in your view controller.h
- (IBAction)butaction:(id)sender; //this is your color change method;
in your view controller.m wherever u add this button
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag=10; //this is important
[self.view addSubview:button];
button1 = [UIButton buttonWithType:UIButtonTypeCustom];
button1.tag=20; //this is important
[self.view addSubview:button1];
//here ur color change method
- (IBAction) butaction:(UIButton*)sender {
switch (sender.tag)
{
case 10:
[button setBackgroundColor:[UIColor blackColor]];
break;
case 20:
[button1 setBackgroundColor:[UIColor blackColor]];
break;
default:
break;
}
}
Try this, it may be helpful
for (int index=1; index<=5; index++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(ButtonClickedFunction:) forControlEvents:UIControlEventTouchUpInside];
button.tag= index;
[view addSubview:button];
};
implement this in IBAction
-(IBAction)ButtonClickedFunction:(UIButton *)button{
button.backgroundColor = [UIColor blackColor];
}
Note: In this I have created 5 buttons but not set frame. Please set frame according to your requirements.
Thanks

Programmatic Custom UIButton Does Not Appear After Timer

I have been trying to write a program in which a button appears after a timer fires. The timer is working properly, as is the firing event (I have tested this with different events). However, the button I am making appear is not showing up. Also, I would like the button background image to change when the button is pressed and held. I have tried making the button just have a background color instead of an image, but that does not work either. The code is located in the Timer selector within the view controller Any help is appreciated. Thanks!
- (void)timerFireMethod:(NSTimer *)timer
{
Button = [UIButton buttonWithType:UIButtonTypeCustom];
Button.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
[Button setBackgroundImage:[UIImage imageNamed:#"buttonUnheldBGImage"]
forState:UIControlStateNormal];
[Button setBackgroundImage:[UIImage imageNamed:#"buttonHeldBGImage"]
forState:UIControlStateHighlighted];
[Button setTitle:#"Press and Hold" forState:UIControlStateNormal];
[Button addTarget:self action:#selector(aSelector:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Button];
}
The timer class that calls this is:
- (void)timer
{
globalTimer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:#selector(timerFireMethod:)
userInfo:Nil
repeats:NO];
}
globalTimer is a global NSTimer
You have set the center of the button but you also need the frame of it, i believe that the button is showing now but his frame is (0,0).
You have to set a size to your button as well. If you want it at the center of your super view just do :
CGRect buttonFrame = CGRectMake(self.view.frame.size.width/2-100,self.view.frame.size.height/2-100, 200,200);
Button.frame = buttonFrame;
The center property is essentialy used for UI Element that already have a size.
Just replace your first 2 lines,
UIButton * Button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
Button.frame = CGRectMake(20, 200, 200, 200);

Dynamically added buttons covering each other in iOS

I'm working on an iOS app (my first - I've been a .NET developer for a very long time).
I'm setting up a dynamically added button - everything works great, except the buttons I'm trying to create are covering each other.
Any thoughts on how to dynamically add buttons and change their positions? (In ASP.NET I'd add a placeholder and controls...but in iOS, that's not an option)
Code:
UIButton btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget: self action:#selector(loadQuestion:) forControlEvents:UIControlEventTouchUpInside;
[btn setTitle:#"My Button" forState:UIControlStateNormal];
btn.frame = CGRectMake(350.0,750.0,160.0,40.0);
[self.view addSubView:btn];
Dont use same X-cordinates for all buttons. See the below code
-(void)addSixButtons{
float xCord = 5.0;
for(int itemIndex = 1; itemIndex < 7; itemIndex++){
UIButton myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton addTarget: self action:#selector(loadQuestion:) forControlEvents:UIControlEventTouchUpInside;
[myButton setTitle:#"My Button" forState:UIControlStateNormal];
myButton.frame = CGRectMake(xCord,750.0,160.0,40.0);
myButton.tag = itemIndex;
[self.view addSubView:myButton];
xCord += 165.0;
}
}
-(void)loadQuestion:(id)sender{
UIButton *btnClicked = (UIButton *)sender;
switch(btnClicked.tag){
case1:
//clicked first button
break;
case2:
//clicked second button
break;
default:
break;
}
}
Here, issue with your code is that you are specifying same frame for the buttons CGRectMake(350.0,750.0,160.0,40.0)
you need to change the x position of the button if you want them to align horizontally and can change y posyion if you want to align them vertically.
In iPhone, positions are specified by frame CGRectMake(x,y,width,height). So, specify different x and y values as per reuirement and can also increment that values if you are using loops.

Hide programmatically created UIButton for tag

Currently I have 14 buttons being created programmatically using a for loop, code below:
int buttonCount = 14;
for (int i=0; i< buttonCount; i++) {
//Create titleString from array object
NSString *stringFromInt = [NSString stringWithFormat:#"%#",[arrayForRound objectAtIndex:i]];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(buttonSelected:)
forControlEvents:UIControlEventTouchDown];
[button setTitle:stringFromInt forState:UIControlStateNormal];
button.titleLabel.font = [UIFont fontWithName:#"helvetica" size:19];
button.tag = i;
[self.view addSubview:button];
}
This works great to create the buttons, I can then populate the Answer Box with the value of the selected button:
-(void)buttonSelected: (UIButton *)sender
{
[_buttonOne setTitle:sender.titleLabel.text forState:UIControlStateNormal];
}
However after the button has been populated I would like to remove it from the screen. If i call button.hidden it simply hides the last button that was programmatically created. I am aware of button.tag and have tried to use this, but it feels like I almost need to do something like:
//Hide button for tag (i know this is incorrect syntax)
button for buttonTag: 3 setHidden;
Is there something similar or a way of doing this?
Update
The button that I am trying to hide is the one that was created programatically. So I want _buttonOne to take on the title of the create button (lets call that letterButton), and then hide letterButton from the view,
UIButton *yourBtn = (UIButton *)[self.button viewWithTag:3];
[yourBtn setHidden:YES];
(code posted by Oh Seung Kwon)
This code work perfectly but it hides the wrong set of buttons. (Hides _buttonOne and not letterButton).
I wonder if it would not be better to create the 12 buttons in nib and name them manually...There will never be more or less that 12.
When your button is tapped, you can set the hidden property on the action method's sender argument, which is the button that actually got tapped. This will hide the button which was tapped.
- (void)buttonSelected:(UIButton *)sender {
[_buttonOne setTitle:sender.titleLabel.text forState:UIControlStateNormal];
[sender setHidden:YES];
}
If you meant to retrieve the button with the tag of 3, you can use this code instead:
[[self.view viewWithTag:3] setHidden:YES];
I don't recommend that you use the tag property - you should use Interface Builder and an IBOutletCollection instead.
Like this
UIButton *yourBtn = (UIButton *)[self.view viewWithTag:3];
[yourBtn setHidden:YES];
You could get the view by tag use this message.
[self.view viewWithTag:3];
We always specific tag by macro just like
#define kFirstButtonTag (100)
or use
#define kButtonBeginTag (100)
Then use the macro to get tag.
And in a special number - Case 0, 1 or 2 is always use, begin your tag in a special number could avoid some problems

Resources