手势识别器在 iOS 4.3 中停止工作
Posted
技术标签:
【中文标题】手势识别器在 iOS 4.3 中停止工作【英文标题】:Gesture recognizer stopped working in iOS 4.3 【发布时间】:2011-03-14 04:02:29 【问题描述】:我的手势识别代码在 ios 4.2 中运行良好,但在 iOS 4.3 中无法运行。我在 iOS 4.2 到 4.3 的手势识别器中找不到任何记录在案的更改,但我已经在 iPad 和模拟器中确认我的代码不再工作。
这就是我正在做的:
在我的视图控制器的 ViewDidLoad 方法中,我输入了:
UISwipeGestureRecognizer *swipeUpGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreenLeft:)] autorelease];
swipeUpGesture.numberOfTouchesRequired = 2;
swipeUpGesture.direction = (UISwipeGestureRecognizerDirectionLeft);
[scrollView addGestureRecognizer:swipeUpGesture];
在 iOS 4.2 中,这可以按预期工作,但在 iOS 4.3 中,即使我用两根手指滑动,也不会调用 swipedScreenLeft。一切都编译并运行,但没有错误或警告。
有什么可能会阻止此手势识别器在 iOS 4.3 中工作,即使它在 iOS 4.2 中运行良好?
我还注意到,在 iOS 4.2 下,如果我用两根手指触摸屏幕但没有做出正确的手势,什么都不会发生,但在 iOS 4.3 中,如果我用两根手指触摸屏幕,就好像我只是用一根手指触摸。好像 iOS 4.3 无法识别我的应用程序中的多点触控事件。
另一个注意事项:我的 tapGestureRecognizer 在 iOS 4.3 中可以正常工作,只是 swipeGestureRecognizer 不能。
【问题讨论】:
同样的问题,在 iOS 4.3 中停止工作,之前很好。 我很高兴找到和我有同样问题的人。如果你想通了,请告诉我,我也会这样做。您的代码是否也在滚动视图上使用手势识别器? 我的手势识别器位于应用程序的主窗口中,因此可以在整个应用程序中使用。 【参考方案1】:问题仅在于 UIScrollView,我也对此大发雷霆:http://i.stack.imgur.com/dqx3d.png
[更新 1] 这里的解决方案:
情况:一个 UIViewController 的视图有一个 UIScrollView 作为子视图(滚动视图分页被禁用)。
我用来将手势附加到 UIView 的代码:
UISwipeGestureRecognizer *swipeLeftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreenLeft:)];
[swipeLeftRecognizer setNumberOfTouchesRequired:2.0f];
swipeLeftRecognizer.delegate = self;
[swipeLeftRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.view addGestureRecognizer:swipeLeftRecognizer];
[swipeLeftRecognizer release];
要启用 iOS 4.3,我只需将 UIViewController 添加为 UIGestureRecognizerDelegate
然后,我使用以下委托方法拦截并允许同时识别滚动视图的 panGesture 和视图的滑动。代码如下:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
if ([gestureRecognizer isKindOfClass:[UISwipeGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
return YES;
return NO;
[更新 2]
要禁用用两根手指平移 UIScrollView,我认为您必须创建滚动视图,这是 UISCrollView 类的自定义子类并更改 panGesture 检测器的某些行为,但我没有尝试这样做。 相反,我选择了一个更懒的解决方案,基本上我根据 UISwipeGestureRecognizer 的当前状态启用/禁用 scrollView 滚动功能。 此外,为了防止在另一个方向上的双重触摸移动,我为此添加了另一个识别器。
您必须为滑动检测器创建两个属性。
@property (nonatomic,assign) UISwipeGestureRecognizer *swipeRightRecognizer;
@property (nonatomic,assign) UISwipeGestureRecognizer *swipeLeftRecognizer;
然后我这样编码:
[self setSwipeRightRecognizer:[[UISwipeGestureRecognizer alloc] initWithTarget:nil action:nil]];
[swipeRightRecognizer setNumberOfTouchesRequired:2.0f];
swipeRightRecognizer.delegate = self;
[swipeRightRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[self addObserver:self forKeyPath:@"swipeRightRecognizer.state" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
[self.view addGestureRecognizer:swipeRightRecognizer];
[swipeRightRecognizer release];
[self setSwipeLeftRecognizer:[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreenLeft:)]];
[swipeLeftRecognizer setNumberOfTouchesRequired:2.0f];
swipeLeftRecognizer.delegate = self;
[swipeLeftRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[self addObserver:self forKeyPath:@"swipeLeftRecognizer.state" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
[self.view addGestureRecognizer:swipeLeftRecognizer];
[swipeLeftRecognizer release];
然后添加这个方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
if (self.swipeRightRecognizer.state == UIGestureRecognizerStateFailed)
self.scrollView.scrollEnabled = YES;
return;
if ([self.swipeRightRecognizer numberOfTouches] != 2.0f)
self.scrollView.scrollEnabled = YES;
else
self.scrollView.scrollEnabled = NO;
并更新我在之前“[UPDATE]”中发布的现有方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
if ([gestureRecognizer isKindOfClass:[UISwipeGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
if ([gestureRecognizer numberOfTouches] != 2.0f)
self.scrollView.scrollEnabled = YES;
else
self.scrollView.scrollEnabled = NO;
return YES;
return NO;
最后,移除 dealloc 中的观察者:
[self removeObserver:self forKeyPath:@"swipeRightRecognizer.state"];
[self removeObserver:self forKeyPath:@"swipeLeftRecognizer.state"];
我敢打赌,有一个更清洁的解决方案,但它确实有效.. .
希望对你有帮助;)
【讨论】:
好的,所以我将 UIGestureRecognizerDelegate 添加到我的主视图控制器的头文件中:@interface MainViewController : UIViewController如果你使用 UIImageView 并且你想处理双击它,你应该启用用户交互。我浪费了很多时间来发现这一点。
【讨论】:
【参考方案3】:也许我的代码可以帮助您解决问题。 我已经在装有 iOS 4.3 的 iPad 上测试了代码 而且效果很好
UISwipeGestureRecognizer *oSwipeLeft = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(mPreviousPage:) ] autorelease];
oSwipeLeft.numberOfTouchesRequired = 2;
oSwipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:oSwipeLeft];
UISwipeGestureRecognizer *oSwipeRight = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(mNextPage:) ] autorelease];
oSwipeRight.numberOfTouchesRequired = 2;
oSwipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:oSwipeRight];
UISwipeGestureRecognizer *oSwipeUp = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(mPreviousPage:) ] autorelease];
oSwipeUp.numberOfTouchesRequired = 2;
oSwipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:oSwipeUp];
【讨论】:
感谢您的回复。似乎您的代码与我的代码相同,只是您将 self.view 放在我放置 scrollview 的位置(我的视图的名称)。我按照你的方式试过了,应用程序似乎仍然无法识别多次触摸。这让我觉得我的代码中的其他地方在 iOS 4.3 中禁用了多点触控,但在 4.2 中没有。出于好奇,您的视图是滚动视图还是其他类型的视图? 我看到问题解决了。在回答您的问题时,我使用的是表格视图。以上是关于手势识别器在 iOS 4.3 中停止工作的主要内容,如果未能解决你的问题,请参考以下文章
使用点击手势识别器时,IOS swift应用程序无法正常工作