是否可以自定义触发 UIScrollView 滚动的滑动手势识别?

Posted

技术标签:

【中文标题】是否可以自定义触发 UIScrollView 滚动的滑动手势识别?【英文标题】:Is it possible to customize swiping gesture recognition that triggers UIScrollView scroll? 【发布时间】:2013-04-25 09:02:59 【问题描述】:

我从UIScrollView 创建了一个自定义子类,并实现了touchesBegantouchesMovedtouchesEndedtouchesCancelled 方法。

但是,我对事情的运作方式并不满意。特别是,提到的方法何时被调用,UIScrollView 何时决定实际滚动(拖动)。

UIScrollView 滚动,即使第一个触摸点和最后一个触摸点在垂直方向上的差异很小。所以我几乎可以水平滑动,UIScrollView 会根据那个微小的差异向上或向下滚动。(这在正常用例中非常好)

这两种滑动都会导致UIScrollView 向下滚动。

但是我很感兴趣,是否可以以某种方式对其进行调整,使其行为如下:

基本上,几乎水平的滑动会被touchesBegan 和相关方法拾取,并且不会启动滚动。然而,绿色的滑动方向仍会启动滚动...

编辑:

我忘了提,touchesBegan 和亲戚如果您在屏幕上按住手指一小段时间然后移动它,就会被呼叫。所以不是经典的滑动手势......

【问题讨论】:

【参考方案1】:

Ivan,我认为您正在尝试做与 Facebook 页面相同的效果,并拖动您的滚动视图,因此让滚动视图跟随您的手指,如果正确,我建议您忘记触摸事件,并从UIPanGesture ,在这些情况下它是最好的,所以在调用该手势的委托中,为其添加以下代码:

    //The sender view, in your case the scollview
    UIScrollView* scr = (UIScrollView*)sender.view;
    //Disable the scrolling flag for the sake of user experience
    [scr setScrollEnabled:false];

    //Get the current translation point of the scrollview in respect to the main view
    CGPoint translation = [sender translationInView:self.view];

    //Set the view center to the new translation point 
    float translationPoint = scr.center.x + translation.x;
    scr.center = CGPointMake(translationPoint,scr.center.y);
    [sender setTranslation:CGPointMake(0, 0) inView:self.view];

【讨论】:

好点!我刚刚尝试了 Facebook 应用程序,似乎就是这样......如果你向左或向右滑动,新闻提要(可能是 UIScrollView)会滑到一边......我现在要试试你的建议。但是我必须注意,我实际上并没有尝试打开侧边菜单,而是实际上改变了 NSInteger 变量(增加/减少)关于水平滑动或拖动的值......【参考方案2】:

Christopher Nassar 正确地指出我应该使用UIPanGestureRecognizer,因此我对其进行了一些试验。

我发现如果您将UIPanGestureRecognizer 添加到包含您的UIScrollViewsuperview。然后UIScrollView 内置平移手势识别器将与您自己的UIPanGestureRecognizer 以我想要的确切方式一起工作!

水平和接近水平的滑​​动将被 superviewUIPanGestureRecognizer 拾取,而所有其他垂直滑动将被内置的平移手势识别器 UIScrollView(自定义)拾取并导致它滚动...

我想UIScrollView 是这样设计的,因为默认行为是只有这些平移手势识别器中的一个触发,或者如果UIScrollView 从这个UIPanGestureRecognizerDelegate 方法返回YES,则同时触发:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

但是,UIScrollView 似乎有额外的逻辑来选择性地禁用(对于水平滑动)它自己的平移识别器,以防另一个存在。

也许这里有人知道更多细节。

所以总结一下,我的解决方案是在我的UIViewController 中的viewDidLoad 中添加一个UIPanGestureRecognizer。(注意:UIScrollView 作为一个 subview 添加到那个@ 987654337@查看)

UIPanGestureRecognizer *myPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.view addGestureRecognizer:myPanGestureRecognizer];

然后添加处理方法:

- (void)handlePan:(UIPanGestureRecognizer *)recognizer

    NSLog(@"Swiped horizontally...");

【讨论】:

以上是关于是否可以自定义触发 UIScrollView 滚动的滑动手势识别?的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 事件处理

自定义 UIView 中的 UIScrollView 不滚动

当我无法使用 UIScrollView 时,如何在自定义 UIView 中模拟惯性滚动?

自定义 UIScrollView 滚动条颜色?

支持 UITableView 的自定义 UIScrollView

UIScrollView 或 UICollectionView 中的自定义滚动行为