在 UITableView 上滑动删除以使用 UIPanGestureRecognizer

Posted

技术标签:

【中文标题】在 UITableView 上滑动删除以使用 UIPanGestureRecognizer【英文标题】:Get Swipe to Delete on UITableView to Work With UIPanGestureRecognizer 【发布时间】:2013-08-22 00:31:26 【问题描述】:

我使用此代码将 UIPanGuestureRecognizer 添加到整个视图中:

UIPanGestureRecognizer *pgr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[[self view] addGestureRecognizer:pgr];

在主视图中,我有一个 UITableView,其中包含启用滑动删除功能的代码:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 
    NSLog(@"RUNNING2");
    return UITableViewCellEditingStyleDelete;


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
    if (indexPath.row >= _firstEditableCell && _firstEditableCell != -1)
        NSLog(@"RUNNING1");
        return YES;
    else
        return NO;

只有RUNNING1 被打印到日志中,删除按钮不显示。我相信这是因为 UIPanGestureRecognizer,但我不确定。如果这是正确的,我应该如何解决这个问题。如果这不正确,请提供原因并修复。谢谢。

【问题讨论】:

您是否将您的班级设置为表格视图的委托? @rdelmar 是的。另外,如果我不这样做,我认为不会打印 RUNNING1 。但是感谢您的尝试。 canEditRorAtIndexPath: 是数据源方法,不是委托方法,所以如果你没有设置委托,它会运行。 @rdelmar 感谢您的澄清,但是我有。 【参考方案1】:

来自document:

如果手势识别器识别出它的手势,则视图的剩余触摸将被取消。

您的UIPanGestureRecognizer 首先识别滑动手势,因此您的UITableView 不再接收触摸。

要使表格视图与手势识别器同时接收触摸,请将其添加到手势识别器的委托中:

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

【讨论】:

正是我想要的。工作精美。谢谢!【参考方案2】:

例如,如果您使用 UIPanGuestureRecognizer 来显示侧边菜单,那么当您在所有情况下都按照接受的答案中的建议返回 YES 时,您可能会看到一些不需要的副作用。例如,当您向上/向下滚动表格视图(具有额外的很少的左/右方向)时打开侧菜单,或者当您打开侧菜单时删除按钮行为异常。为了防止这种副作用,您可能想要做的是只允许同时进行水平手势。这将使删除按钮正常工作,但同时当您滑动菜单时其他不需要的手势将被阻止。

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

    if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
    
        UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)otherGestureRecognizer;
        CGPoint velocity = [panGesture velocityInView:panGesture.view];
        if (ABS(velocity.x) > ABS(velocity.y))
            return YES;
    
    return NO;

或在 Swift 中:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool 
    guard let panRecognizer = otherGestureRecognizer as? UIPanGestureRecognizer else 
        return false
    
    let velocity = panRecognizer.velocity(in: panRecognizer.view)
    if (abs(velocity.x) > abs(velocity.y)) 
        return true
    
    return false

【讨论】:

【参考方案3】:

如果接受的答案不起作用。尝试添加

panGestureRecognizer.cancelsTouchesInView = false

确保您没有直接将手势添加到 tableview。我在 ViewController 视图上添加了一个平移手势,并且可以确认它有效。

【讨论】:

以上是关于在 UITableView 上滑动删除以使用 UIPanGestureRecognizer的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 区分滑动删除和多行选择

在uitableview单元格上留下滑动删除按钮打开然后返回导致崩溃

在 Xamarin IOS 的 UITableview 中更改滑动以删除按钮高度

iOS 7 UITableView 问题 - 当我们已经有一个单元格时尝试设置滑动以删除单元格

iOS 从 UITableView 滑动以删除 plist 中的数组

UITableView:向上滑动时收缩标签栏和导航栏