Reputation: 49743
New to iPhone dev. I have a view which contains a UIScrollView which contains a UIImageView. I added a (double) tap gesture recognizer on the image view which makes an alert box open. For some reason, and I'm sure I'm just retarded, it opens 3 times.
Here's my code:
- (void)viewDidLoad {
scrollView.delegate = self;
UIImage* image = imageView.image;
imageView.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
scrollView.contentSize = image.size;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 2;
[imageView addGestureRecognizer:tapGesture];
[tapGesture release];
NSLog(@"LOADED");
[super viewDidLoad];
}
-(IBAction) handleTapGesture:(UIGestureRecognizer *) sender {
CGPoint tapPoint = [sender locationInView:imageView];
int tapX = (int) tapPoint.x;
int tapY = (int) tapPoint.y;
NSLog(@"TAPPED X:%d Y:%d", tapX, tapY);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"How are you?" delegate:nil cancelButtonTitle:@"I'm awesome." otherButtonTitles:nil];
[alert show];
[alert release];
}
I just started iPhone dev a few days ago. This problem kind of reminds me of event bubbling issues I've dealt with in javascript. Any ideas?
Upvotes: 4
Views: 16510
Reputation:
Not sure what the exact reason is but the UIAlertView is somehow causing the gesture to fire again. A workaround is to execute the showing outside the gesture handler using performSelector:
-(void) handleTapGesture:(UIGestureRecognizer *) sender {
CGPoint tapPoint = [sender locationInView:imageView];
int tapX = (int) tapPoint.x;
int tapY = (int) tapPoint.y;
NSLog(@"TAPPED X:%d Y:%d", tapX, tapY);
[self performSelector:@selector(showMessage) withObject:nil afterDelay:0.0];
}
- (void)showMessage
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"How are you?" delegate:nil cancelButtonTitle:@"I'm awesome." otherButtonTitles:nil];
[alert show];
[alert release];
}
Edit:
The gesture recognizer goes through different states in the gesture (Began, Changed, etc) and it calls the handler method each time the state changes. So a better and probably correct solution is to check the state property of the gesture recognizer at the top of the handler:
-(void) handleTapGesture:(UIGestureRecognizer *) sender {
if (sender.state != UIGestureRecognizerStateEnded) // <---
return; // <---
CGPoint tapPoint = [sender locationInView:imageView];
int tapX = (int) tapPoint.x;
int tapY = (int) tapPoint.y;
NSLog(@"TAPPED X:%d Y:%d", tapX, tapY);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"How are you?" delegate:nil cancelButtonTitle:@"I'm awesome." otherButtonTitles:nil];
[alert show];
[alert release];
}
Upvotes: 10