UIButton touchUpInside event not firing correctly - iphone

I have a tableview that contains a row with a custom cell that contains a UIButton. However, the button doesn't always fire the action. Here's my code:
submitButton = [[UIButton alloc] init];
[[submitButton layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[submitButton setClipsToBounds: YES];
submitButton.backgroundColor = [UIColor grayColor];
[submitButton setTitle:#"Send" forState:UIControlStateNormal];
[self.contentView addSubview:submitButton];
[submitButton addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[submitButton release];
This is called in the custom cell's -(id)initWithStyle:
The buttonAction method looks like this:
-(void)buttonAction
{
NSLog(#"Button Clicked!");
}
It seems that the only way I can get the buttonAction to fire is if I press down on the button and release somewhere inside the cell's frame, but not inside the button itself. Why would that be?
*UPDATE*
Problem still exists, but I found that the more consistent way to get the button to fire is to click and drag to the left or right and then let go, as long as I let go within the bounds of the cell/row.
UPDATE #2
It looks like if I use iOS 6.0, it works as intended. But on 5.0 or 5.1 it does not.

Try assigning the same method call to TouchUpOutside as well - you should then see it work every time. TouchUpInside is only fired if you lift your finger while still within the bounds of the button.

Try [submitButton sizeToFit]. I'm wondering whether your button has any size (since I don't see you giving it any).
Also: Create your button with [UIButton buttonWithType: UIButtonTypeCustom] instead of alloc-init.

Related

UIControl track touches outside its view

I'm building a menu as a subclass of UIControl that opens when a user touches it and will close if a user doesn't choose one of its options.
I'm looking for a way to track when a user touches outside so that I can close the menu
Put one view behind your menu that cover whole area of your device with background of clear color. when your menu is open make that view visible. as it has same height and width as your device whenever you click outside the menu you can identify that view using TapGesture or make it UIControl. than call method to hide both your menu and that uiview.
Hope this will help.
What I really like to do is to make a big button that covers the entire view, and have it below the menu, or whatever else I want to touch away from and have something happen.
UIButton *bigBackButton = [[UIButton alloc]initWithFrame:self.view.frame];
[bigBackButton addTarget:self action:#selector(backButtonSelected) forControlEvents:UIControlEventTouchDown];
[bigBackButton setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]];
[self.view addSubview:bigBackButton];
}
- (void)backButtonSelected:(UIButton *)button {
//get rid of the button
[button removeFromSuperview];
//do whatever else you need to do
[yourmenu dosomething];
}
on some apps, I'll make the button dark and translucent to highlight the menu, whatever else. Other times I'll make it pretty much invisible, like [UIColor colorWithWhite:1.0 alpha:0.01];
in your menu routine you could add these same routines. You could pass the frame of the parent view, or just look it up in the layoutSubviews routine, if your menu is a sublcass of a UIView.
in your layoutSubviews, add this:
UIButton *bigBackButton = [[UIButton alloc]initWithFrame:self.superview.frame];
[bigBackButton addTarget:self action:#selector(backButtonSelected) forControlEvents:UIControlEventTouchDown];
[bigBackButton setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]];
[self.view addSubview:bigBackButton];
and then put the backButtonSelected method in your menu class as well.

How to make toggle image button instead of UIBarButtonItem in iphone programming?

I have to make a button in UINavigationBar, the button should toggle between restart state and cancel state, and it should call
-(void)RestartMethod {}
at restart state and should call method
-(void) cancelMethod {}
at cancel state of UIBarButtonItem,both states are using images like start.png and calcel.png
I tried by making two images and add and remove targets,b but facing some bad-exec issues,
how can I do it?
Help!
item1=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"DoneUp3.png"] style:UIBarButtonItemStylePlain target:self action:#selector(action1)];
item2=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"Pin.png"] style:UIBarButtonItemStylePlain target:self action:#selector(action2)];
-(void)action1{self.navigationItem.rightBarButtonItem = item2;}
-(void)action2{self.navigationItem.rightBarButtonItem = item1;}
Create two buttons with two different targets. When one button is clicked do whatever you want the action to be and replace the button with button number two. If button number two is clicked, replace that with button number 1.
Why not use a segment control instead of toggle button? Even if you insist on using a single button to toggle, this is how I would achieve it.
Have a bool declare the initial state
BOOL buttonOn = NO;
Embed the first button with initial image pointing to one selector
Inside selector take action based on this boolean. Change state and change this boolean's value too. No need to have two different selectors. Call appropriate functions to do stuff inside this selector.
i think this can help you:
CGRect frameimg = CGRectMake(0, 0, image3.size.width, image3.size.height);
UIButton *someButton = [[UIButton alloc] initWithFrame:frameimg];
[someButton setBackgroundImage:[UIImage imageName:#"start.png"] forState:UIControlStateNormal];
[someButton setBackgroundImage:[UIImage imageName:#"calcel.png"] forState:UIControlStateSelected];
[someButton addTarget:self action:#selector(backButtonPress:)forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *mailbutton =[[UIBarButtonItem alloc] initWithCustomView:someButton];
self.navigationItem.leftBarButtonItem=mailbutton;
[mailbutton release];
New write backButtonPress: method:
-(void)backButtonPress:(id)sender{
UIButton *tmpButton = (UIButton *)sender;
tmpButton.selected = [tmpButton isSelected]?NO:YES;
if (tmpButton.selected) {
// call cancelMethod or write RestartMethod code here
}
else{
// call RestartMethod or write RestartMethod code here
}
}

iPhone SDK - UIButton Highlighted State Question

I am having trouble with the behavior of one of my UIButtons. I am trying to essentially make it a toggle button, but I am running into the problem below.
I have the code:
UIButton *likeButton = [[UIButton alloc] initWithFrame:CGRectMake(horizontalOffset+buttonWidth, verticalOffset, buttonWidth, buttonHeight)];
[likeButton setImage:[UIImage imageNamed:#"like-off.png"] forState:UIControlStateNormal];
[likeButton setImage:[UIImage imageNamed:#"like-on.png"] forState:UIControlStateHighlighted];
[likeButton setImage:[UIImage imageNamed:#"like-on.png"] forState:UIControlStateSelected];
[likeButton addTarget:self action:#selector(likeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
which fires the method:
-(void)likeButtonPressed:(id)sender {
UIButton *button = (UIButton *)sender;
[button setSelected:!button.selected];
}
The behavior I am seeing is that when I tap the button down (and highlight it), it works as expected, and the 'like-on.png' image is used for the highlighted state, and it remains on in the 'selected' state.
However, when I tap the button again, to toggle it off, I see a gray highlighted state when I press my finger. When I release my finger, I see the 'like-off' image is shown as expected.
I would like to avoid seeing the gray highlighted state when I press my finger down on the button when I go to toggle it off. Instead I would like to make sure that the highlighted state on toggle-off uses the 'like-on.png' image as specified in the code.
What's going on here? Any ideas where my code could be incorrect?
Many thanks,
Brett
You're missing the image for the selected and highlighted state:
[likeButton setImage:[UIImage imageNamed:#"like-on.png"] forState:UIControlStateSelected | UIControlStateHighlighted];
If you don't set it, the image of the normal state is used. From the -[UIButton setImage:forState:] documentation:
In general, if a property is not specified for a state, the default is to use the UIControlStateNormal value.
If you don't want your images to be modified when they are highlighted, set:
likeButton.adjustsImageWhenHighlighted = NO;
I think the selected property of UIButton is meant for something different (think of the desktop UI).
It would be more consistent to change the for all states according to a BOOL that tracks if it is "on" or "off".
Thus,
-(void)likeButtonPressed:(id)sender {
UIButton *button = (UIButton *) sender;
liking = !liking;
if (liking) {
// configure the four states with "like-on" and other images
}
else {
// configure the four states with "like-off"
}
}
Otherwise you would use the state of a UI element to represent your program logic, which is basically flawed. The only instance where this is sort of acceptable (but not really) is a UISwitch.

UIButton oversensitive

I have a UIButton defined within a tableviewCellWithReuseIdentifier.
The button works but it's very touchy. If I just tap the button it works. Pressing it any long fails to trigger the action, even though it does flash showing that it knows it was pressed. Why is this happening? More importantly, how can I fix it.
Here is the code for the UIButton within the cell.
CGRect rect = CGRectMake(190.0, 2.0, 40.0, ROW_HEIGHT);
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTag:LBUTTON_TAG];
[button setFrame:rect];
[button addTarget:self action:#selector(leftbutton:) forControlEvents:UIControlEventTouchUpInside];
[button setAlpha:0.5];
[cell addSubview:button];
A long shot, but: do you have any asynchronous background processes that might be calling [tableView reloadData] between tap-down and tap-up? That might cause UITableViewCell's mouse tap handling to reset some internal data that makes it "forget" the tap-down inside the button, which could cause it to not fire the UIControlEventTouchUpInside event since it doesn't remember the tap-down.
Possibly because your finger is moving slightly so UIScrollView (which UITableView is a subclass of) thinks it's a drag?
Try setting tableView.canCancelContentTouches = NO.

Not calling the function when I click on UIButton?

I have an imageView and after i add it to the screen I release it.
Before that I adds a button onto it with this code.
button = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
button.frame = CGRectMake(128.00, 128.00, 23.00, 40.00);
[button setBackgroundImage:[UIImage imageNamed:#"move.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(showAddress:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:button];
- (void) showAddress:(id)sender
{
NSLog(#"Working");
}
The button appears but nothing happens when I click on it to call a function. Not even the pressing-unpressing. Is this because I am releasing the imageView?
Edited:Check if userInteractionEnabled property of your UIImageView is set to YES - it is set to NO by default and that's why UIImageView (and its subviews) does not respond to touch events. I've just set it to YES in my code and it works fine.
One more note - when you add your button to another view it takes the ownership of the button and as you retained it in your code you should also release it. (Or just not retain in this case)