UIScrollView 只能用一根手指滚动
Posted
技术标签:
【中文标题】UIScrollView 只能用一根手指滚动【英文标题】:UIScrollView scrolling only with one finger 【发布时间】:2015-03-13 11:42:49 【问题描述】:ios7 和 iOS8
我需要在UIScrollview
中禁用两指或三指滚动。
我试过了:
[self.scrollView.panGestureRecognizer setMaximumNumberOfTouches:1];
[self.scrollView.panGestureRecognizer setMinimumNumberOfTouches:1];
但它没有效果。仍然可以用两根手指滚动。
如果我尝试将 max 和 min 设置为 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;
有人知道,它是如何解决这个问题的吗?
谢谢。
【问题讨论】:
此链接可能会有所帮助:***.com/questions/8210614/… 【参考方案1】:问题:
当 UIPanGestureRecognizer
是 UIScrollView
的底层时 - 不幸的是,这也会影响 UIPageViewController
- maximumNumberOfTouches
的行为不符合预期,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 类并且想要非常安全,您还可以再添加一行代码来消除与其他 scrollView 的歧义:
- (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 告诉您触摸的次数。如果您将 min 和 max 设置为相同的值(如上例中的 1),则 @ 987654338@ 永远不会被触发... ;-)
这就是为什么 maximumNumberOfTouches
必须至少是 minimumNumberOfTouches + 1
panGestureRecognizer.minimumNumberOfTouches = 1;
panGestureRecognizer.maximumNumberOfTouches = minimumNumberOfTouches + 1;
极客部分:
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
的底层滚动视图的方法。将此代码放在例如UIPageViewController
(自己)的viewDidLoad:
。
如果您根本无法访问滚动视图 - 例如动态 UITableViewCell
中的 UIPageViewController
,其中创建和单元重用发生在运行时,并且无法在其 contentViews 上设置任何出口 - 将类别放在UIScrollView
并覆盖那里的委托方法。不过要小心!这会影响您的应用程序中的每个滚动视图 - 所以要像上面的“更安全”示例中那样进行适当的自省(类检查)...... ;-)
旁注:
不幸的是,同样的技巧不适用于 pinchGestureRecognizer
上的 UIScrollView
,因为它不公开 min/maxNumberOfTouches
属性。当被监控时,它总是报告 2 次触摸(你显然需要捏) - 所以它的内部 min/maxNumberOfTouches
似乎都设置为 2 - 即使 UIScrollView
不遵守自己的设置,并且一直在愉快地用任意数量的手指(超过 2 个)进行捏合。所以没有办法将捏合限制在有限数量的手指上......
【讨论】:
【参考方案2】:我可以确认这在 iOS 8 中仍然是一个问题,但前提是 UIPanGestureRecognizer 是 UIScrollView 的基础。使用新的 UIPanGestureRecognizer 创建 UIView 并设置其 maximumNumberOfTouches 属性按预期工作。
有趣的提示:如果您在滚动时查询 UIScrollView 的 UIPanGestureRecognizer,它会报告触摸次数小于或等于最大值。换句话说,如果您将最大值设置为 2,并用 3 根手指滚动,它会将手势报告为 2 根手指滚动。随后,在继续滚动的同时一次放开一个手指(但不是始终如一)也会减少报告的触摸次数 - 因此,如果您从 3 -> 2 -> 1 个手指开始,它将记录 2 -> 1 -> 0 次触摸,当您还有 1 根手指在设备上时停止滚动。
提交rdar://20890684并复制到http://openradar.appspot.com/radar?id=6191825677189120。请随意欺骗。
【讨论】:
【参考方案3】:没有具体的方法可以解决这个问题,只是做一些技巧,但结果只有 75%。
向您的 UIScrollview 添加滑动手势(每个 4 个方向)和双击手势。然后使用下面的代码..
[[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeDown];
[[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeLeft];
[[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeRight];
[[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:swipeUp];
[[yourScrollView panGestureRecognizer] requireGestureRecognizerToFail:doubleTap];
【讨论】:
【参考方案4】:这将为您完成工作:
yourscrollView.multipleTouchEnabled=NO;
【讨论】:
不会阻止两指或三指滚动。 (在 iOS 12 中测试)。以上是关于UIScrollView 只能用一根手指滚动的主要内容,如果未能解决你的问题,请参考以下文章