ios-仅用一根手指滚动UIScrollView

codeday· 2019-11-17
本文来自 codeday ,作者 codeday
iOS7和iOS8上

我需要禁用2或3个手指在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;
        }

    }

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

谢谢.

最佳答案
问题:

当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;
    }
}

附加信息:

NSLogs会告诉您触摸的次数.如果将最小值和最大值设置为相同的值(如上例中的1),则if循环将永远不会触发… ?

这就是为什么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分页的基础scrollView的方法.将此代码放在例如UIPageViewController(自身)的viewDidLoad:.

如果您根本无法访问scrollView-就像动态UITableViewCell中的UIPageViewController一样,在运行时会进行创建和单元重用,并且无法在其contentViews上设置出口-请在UIScrollView上放置一个类别,并在那里重写委托方法.不过要小心!这会影响应用程序中的每个scrollView-像我上面的“ EVEN SAFER”示例中那样进行适当的自省(类检查)… ?

边注:

不幸的是,相同的技巧对UIScrollView上的pinchGestureRecognizer无效,因为它没有公开min / maxNumberOfTouches属性.受到监视时,它始终报告2次触摸(显然您需要捏一下)-因此其内部的min / maxNumberOfTouches似乎都已设置为2-即使UIScrollView不遵循其自身的设置并保持愉快地用任意数量的手指捏住(大于2).因此,没有办法将捏紧限制为有限的手指…