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; } }
有谁知道,它如何解决这个问题?
谢谢。
问题:
当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类,并且想要非常安全,你还可以添加一行代码来消除其他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告诉你触摸的次数。 如果将min和max都设置为相同的值(如上例中的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];