iOS多手势冲突问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS多手势冲突问题相关的知识,希望对你有一定的参考价值。

参考技术A 首先要搞清楚手势的几个BOOL值和代理方法

假如现在有个tableView加在scrollView上,需求让scrollView滚动到一定位置后在响应table的滚动事件,如下图:

首先,手势默认是互斥的,由事件的响应链可知,如果当前事件有被处理,那么事件将不会继续向上传递,意味着如果滑动tableView,父试图scrollView是不会响应的,显然就不是我们想要的。所以首先就需支持多手势

然后就是一些细节处理,在scrollView的代理方法里边设置边界值,进行简单的逻辑处理,滑动到某一个值就停下来

这里只是简单的一个demo,对手势冲突的一个简单处理,欢迎讨论。
附上 Demo

UITableView滑动删除iOS上的手势冲突

【中文标题】UITableView滑动删除iOS上的手势冲突【英文标题】:Gestures Conflict on UITableView swipe to delete iOS 【发布时间】:2014-08-27 11:37:40 【问题描述】:

我的手势识别器有问题。我的目标是在我的表格视图中使用滑动来删除。但我认为其他手势相互冲突。我正在使用这个库 romaonthego/REFrostedViewController 这是一个用于我的汉堡菜单的库,并且这个库有一个 pangesture 功能。我认为冲突在于手势。因为当我在另一个项目中运行我的 tableview 代码时它正在工作。请帮助,提前谢谢你。

【问题讨论】:

我认为……您必须禁用“panGestureEnabled”并手动显示“菜单”[self.frostedViewController presentMenuViewController]; 但我还需要平移手势。我禁用了平移手势,但它根本不起作用。我看到一些应用程序在菜单上使用平移手势和手势来删除表格中的数据。我想知道他们是如何管理两个 run 2 pan 手势的。 T_T 但是.. 你有什么冲突?无法显示菜单……或者无法滑动单元格? 我无法滑动单元格。 嘿哥们你是怎么解决这个问题的? 【参考方案1】:

我遇到了类似的问题,我最终做的与 TonyMkenu 类似,但您需要允许更多识别器:

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

if (otherGestureRecognizer.delegate == self )
    return NO;

//if otherGestureRecognizer is swipe to delete from a UITableView cancel slide menu recognizers

if ([[otherGestureRecognizer.view class] isSubclassOfClass:[UITableView class]])

    NSLog(@"Allow1 %@", [otherGestureRecognizer description]);

    return YES;


if( [[otherGestureRecognizer.view class] isSubclassOfClass:[UITableViewCell class]] ||
[NSStringFromClass([otherGestureRecognizer.view class]) isEqualToString:@"UITableViewCellScrollView"] ||
[NSStringFromClass([otherGestureRecognizer.view class]) isEqualToString:@"UITableViewWrapperView"])

    NSLog(@"Allow&Disable %@", [otherGestureRecognizer description]);

    if(gestureRecognizer.delegate == self)
    //cancel the slide menu recognizer

        gestureRecognizer.enabled = NO;
        gestureRecognizer.enabled = YES;
    

    return YES;


NSLog(@"Deny %@", [otherGestureRecognizer description]);
return NO;

【讨论】:

【参考方案2】:

编辑:针对 iOS 11 更新

其他答案很有帮助,但就我而言,最好的解决方案是像这样在shouldRequireFailureOfOtherGesture 中执行逻辑:

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

    if (gestureRecognizer == self.pan) 
        return YES;
    
    return NO;


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

    if (gestureRecognizer == self.pan) 

        // iOS 10
        if ([NSStringFromClass([otherGestureRecognizer.view class]) isEqualToString:@"UITableViewWrapperView"]) 
            return YES;
        
        // iOS 11
        else if ([otherGestureRecognizer isMemberOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer.view isKindOfClass:[UITableView class]]) 
            return YES;
        
    
    return NO;

在我的情况下,这具有更好的行为。我还在平移手势上使用了delaysTouchesBegan = YES。可能有用!

【讨论】:

UITableViewWrapperView 未在 iOS 11 中使用。有人让它在 iOS 11 中工作吗? @thejaz 我更新了 iOS 11 的答案,希望对您有所帮助! 我还是没有运气【参考方案3】:

在 iOS 11 中,希望对你有所帮助。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
    if ([[otherGestureRecognizer.view class] isSubclassOfClass:[UITableView class]]) 
        if ([otherGestureRecognizer isKindOfClass: [UIPanGestureRecognizer class]]) 
            UIPanGestureRecognizer *otherPan = (UIPanGestureRecognizer *)otherGestureRecognizer;
            CGPoint translation = [otherPan translationInView:otherGestureRecognizer.view];
            return translation.x < 0;
        
    
    return NO;

【讨论】:

【参考方案4】:

首先...检查你是否有这个

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    // Return NO if you do not want the specified item to be editable.
    return YES;

第二个……

尝试添加这个

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

    if ([gestureRecognizer.view isKindOfClass:[UITableView class]]) 
       return YES;
     else 
       return NO;
    

https://***.com/a/14338043

【讨论】:

那么...你有什么消息吗? 抱歉回复晚了,我已经通过引用我的汉堡菜单的手势来解决我的问题。谢谢你的回答:) @AlvinJohnTandoc 我在当前项目中遇到了类似的问题。我认为 TonyMkenu 提供的解决方案对您有用。如果我的假设是正确的,请告诉我将代码放在哪里(答案中提供的功能)?现在我的代码没有在任何地方使用这些功能。那么我应该把它放在菜单类还是我自己的视图控制器类中?

以上是关于iOS多手势冲突问题的主要内容,如果未能解决你的问题,请参考以下文章

iOS 捏合手势与滑动手势冲突

iOS解决嵌套在ScrollView中的TableView滑动手势冲突问题

关于iOS抽屉MMDrawerController手势冲突

JSON数据存储对象唯一和手势冲突

iOS-UIScrollView滑动与手势冲突

iOS 手势冲突