UIScrollView只用一根手指滚动

iOS7和iOS8

我需要在UIScrollview禁用2或3个手指滚动。

我试过了 :

 [self.scrollView.panGestureRecognizer setMaximumNumberOfTouches:1]; [self.scrollView.panGestureRecognizer setMinimumNumberOfTouches:1]; 

但它没有效果。 仍然可以用两根手指滚动。

如果我试图将最大值和最小值设置为2.一个手指滚动被禁用但3个手指滚动可能:(

我也试过这个,但没有成功:

 for (UIGestureRecognizer* pan in self.scrollView.gestureRecognizers) { OTTNSLog(@"touches: %ld", (unsigned long)pan.numberOfTouches); if ([pan isKindOfClass:[UIPanGestureRecognizer class]]) { UIPanGestureRecognizer *mpanGR = (UIPanGestureRecognizer *) pan; mpanGR.minimumNumberOfTouches = 1; mpanGR.maximumNumberOfTouches = 1; } if ([pan isKindOfClass:[UISwipeGestureRecognizer class]]) { UISwipeGestureRecognizer *mswipeGR = (UISwipeGestureRecognizer *) pan; mswipeGR.numberOfTouchesRequired = 1; } } 

有谁知道,它如何解决这个问题?

谢谢。

问题:

UIPanGestureRecognizerUIScrollView基础 – 不幸的是它也影响UIPageViewControllermaximumNumberOfTouches没有按预期运行时, minimumNumberOfTouches总是正确地限制下端。

在监控这些参数时,它们会报告正确的值 – 它们似乎完成了它们的工作 – 只是UIScrollView本身不尊重它们并忽略它们的设置!


解:

minimumNumberOfTouches设置为所需的值,例如1和 – 非常重要的是 – maximumNumberOfTouches为2 !!!

 myScrollView.panGestureRecognizer.minimumNumberOfTouches = 1; myScrollView.panGestureRecognizer.maximumNumberOfTouches = 2; 

在scrollView的@interface声明中符合UIGestureRecognizerDelegate协议。 您不必为UIScrollView设置panGestureRecognizer.delegate ! 委托已经设置,因为UIScrollView需要成为其自己的pan/pinchGestureRecognizer

然后实现UIGestureRecognizer委托方法:

 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { NSLog(@"%d", gestureRecognizer.numberOfTouches); NSLog(@"%@", gestureRecognizer.description); if (gestureRecognizer == self.panGestureRecognizer) { if (gestureRecognizer.numberOfTouches > 1) { return NO; } else { return YES; } } else { return YES; } } } 

一个更安全的版本:

如果你有一个自定义的scrollView类,并且想要非常安全,你还可以添加一行代码来消除其他scrollViews的歧义:


 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { NSLog(@"%d", gestureRecognizer.numberOfTouches); NSLog(@"%@", gestureRecognizer.description); if ([gestureRecognizer.view isMemberOfClass:[MY_CustomcrollView class]]) { if (gestureRecognizer == self.panGestureRecognizer) { if (gestureRecognizer.numberOfTouches > 1) { return NO; } else { return YES; } } else { return YES; } } else { return YES; } } 

附加信息:

NSLog告诉你触摸的次数。 如果将minmax都设置为相同的值(如上例中的1), if-loop永远不会触发if-loop …… 😉

这就是为什么maximumNumberOfTouches必须至少为minimumNumberOfTouches + 1

 panGestureRecognizer.minimumNumberOfTouches = 1; panGestureRecognizer.maximumNumberOfTouches = minimumNumberOfTouches + 1; 

GEEK部分:

 for (UIView *view in self.view.subviews) { if ([view isKindOfClass:[UIScrollView class]]) { NSLog(@"myPageViewController - SCROLLVIEW GESTURE RECOGNIZERS: %@", view.gestureRecognizers.description); ((UIPanGestureRecognizer *)view.gestureRecognizers[1]).minimumNumberOfTouches = 1; ((UIPanGestureRecognizer *)view.gestureRecognizers[1]).maximumNumberOfTouches = 2; } } 

这是访问负责UIPageViewController分页的底层scrollView的UIPageViewController 。 将此代码放在UIPageViewController (self)的例如viewDidLoad:中。

如果您根本无法访问scrollView – 例如动态UITableViewCell中的UIPageViewController ,其中创建和单元重用在运行时发生,并且无法在其contentView上设置出口 – 在UIScrollView上放置一个类别并覆盖委托方法。 不过要小心! 这会影响应用程序中的每个scrollView – 所以要进行适当的内省(类检查),就像我上面的’EVEN SAFER’示例… 😉


边注:

不幸的是,同样的技巧不适用于UIScrollView上的pinchGestureRecognizer ,因为它没有公开min/maxNumberOfTouches属性。 在监视时,它总是报告2次触摸(你显然需要捏) – 所以它的内部min/maxNumberOfTouches似乎已被设置为2 – 即使UIScrollView没有遵守自己的设置并且保持愉快地用任意数量的手指捏(超过2)。 所以没有办法限制捏到有限数量的手指……

这将为您完成工作:

 yourscrollView.multipleTouchEnabled=NO; 

我可以确认这仍然是iOS 8中的一个问题,但只有当UIPanGestureRecognizer是UIScrollView的基础时。 使用新的UIPanGestureRecognizer创建UIView并设置其maximumNumberOfTouches属性按预期工作。

有趣的说明:如果您在滚动时查询UIScrollView的UIPanGestureRecognizer,它会将触摸次数报告为小于或等于最大值。 换句话说,如果您将最大值设置为2,并使用3个手指滚动,则会将手势报告为双指滚动。 随后在继续滚动的同时一次放一个手指(但不一致)会减少报告的触摸次数 – 所以如果你从3 – > 2 – > 1手指,它将注册2 – > 1 – > 0触摸,并在设备上还有一根手指时停止滚动。

提交rdar:// 20890684并复制到http://openradar.appspot.com/radar?id=6191825677189120 。 请随意欺骗。

没有具体的方法可以做一些技巧,但结果只有75%。

添加滑动手势(每个4个方向)并双击手势到您的UIScrollview ..然后使用下面的代码..

  [[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeDown]; [[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeLeft]; [[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeRight]; [[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeUp]; [[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:doubleTap];