我已经在我的视图控制器的viewDidLoad上设置了一个UITapGestureRecognizer,但不知怎的,它只需点击两次选择器方法。
UITapGestureRecognizer *g = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openInMapsApp:)] autorelease];
[self.mapView addGestureRecognizer:g];
我的方法:
-(void)openInMapsApp:(UIGestureRecognizer*)g {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@""
message:@"This will open this location in the Maps application. Continue?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK",nil];
[alertView show];
[alertView release];
}
答案 0 :(得分:19)
手势识别器以不同的手势状态发送动作。所以这不是一个错误。解决方法是:
UITapGestureRecognizer *g = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openInMapsApp:)] autorelease];
[self.mapView addGestureRecognizer:g];
-(void)openInMapsApp:(UIGestureRecognizer*)g {
if(g.state != UIGestureRecognizerStateRecognized)
return;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@""
message:@"This will open this location in the Maps application. Continue?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK",nil];
[alertView show];
[alertView release];
}
答案 1 :(得分:6)
我有一个双UIAlertView
出现。如上面的Nicolas Rostov所示,这对我有用。当UIGestureRecognizerStateEnded
在块中使用时,UIGestureRecognizerStateRecognized
和[alertView show]
状态都创建了新的alertView。随着// [alertView show]被注释掉,它们仍然出现在控制台上,但只发生了一个动作。
-(void) handleTapGesture:(UIGestureRecognizer*)sender{
if(sender.state != UIGestureRecognizerStateRecognized)
return;
答案 2 :(得分:4)
我可以确认一样。我向Apple提交了一个错误报告,其中有一个示例项目来证明这个问题。
我发现的临时解决方法是在显示警报之前立即禁用UITapGestureRecognizer。然后,在您实现的UIAlertView委托方法中,重新启用它。这需要你以某种方式跟踪GR,但它似乎是时间最优雅的解决方案。
使用上面的示例代码:
-(void)openInMapsApp:(UIGestureRecognizer*)g {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@""
message:@"This will open this location in the Maps application. Continue?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK",nil];
g.enabled = NO;
self.activeGestureRecognizer = g;
[alertView show];
[alertView release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
self.activeGestureRecognizer.enabled = YES;
self.activeGestureRecognizer = nil;
}
- (void)alertViewCancel:(UIAlertView *)alertView {
self.activeGestureRecognizer.enabled = YES;
self.activeGestureRecognizer = nil;
}
答案 3 :(得分:4)
我遇到了同样的问题,我注意到第二个事件的状态是UIGestureRecognizerStateCancelled(而第一个事件是UIGestureRecognizerStateEnded),所以另一种解决方法是在这种情况下忽略该事件。
答案 4 :(得分:3)
我刚刚解决了类似的问题。事实证明,我使用相同的调用将两个轻敲手势识别器添加到视图中。我发现的方法是在调用选择器时通过NSLogging手势识别器。
在您的位置,我会检查以确保您没有两个手势识别器 - 一个来自故事板,另一个以编程方式创建。
NSLog(@"recognizer: %@",[gestureRecognizer description]);
答案 5 :(得分:2)
我在视图中添加了一个计时器,用于检查触摸是否至少是半秒钟,如果太快则忽略第二次触摸。
这只是一种解决方法。我仍然想解决真正的问题。
答案 6 :(得分:1)
if(g.state != UIGestureRecognizerStateBegan)
//instead of if(g.state != UIGestureRecognizerStateRecognized)
return;
这将在手势事件后立即调用alertview。例如:如果您使用longtap事件,一旦您将手指关闭,将显示警报视图。但如果自动识别手势,将自动调用UIGestureRecognizerStateBegan状态。
答案 7 :(得分:-1)
我这样做并且工作了:
首先初始化存储最后一次滑动NSTimeInterval
的处理对象的成员-(id)initWithResourcePath:(NSString*)path {
if ([super init]) {
//some code
lastSwipe = 0;
}
return self;
}
然后将此代码添加到您的方法
-(void)viewDetectedRightSwipe:(UISwipeGestureRecognizer*)recognizer {
//touch being registered
NSTimeInterval thisTouch = [NSDate timeIntervalSinceReferenceDate];
//if the last swipe is the first swipe, then there's nothing to do but the handling of a correct gesture
if(lastSwipe !=0) {
// find out how much time has passed between gestures
NSTimeInterval timeSinceLastTouch = thisTouch -lastSwipe ;
NSLog(@"thisTouch = %f",thisTouch);
NSLog(@"timeSinceLastTouch = %f",timeSinceLastTouch);
if (timeSinceLastTouch<0.2f) {
//return if this is an invalid touch
return;
} else {
// register the timestamp if it is valid
lastSwipe = thisTouch;
NSLog(@"left");
}
}
// invalid gestures won't be registed because they won't get to this portion of code.
lastSwipe = thisTouch;
NSLog(@"left");
// rest of the handling code
}