You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何禁用UITableView中UITableViewCell侧滑删除时的回弹效果?

解决UITableViewCell侧滑自定义按钮时无法停止滑动的问题

嘿,我之前用那个教程的第4种方案实现自定义侧滑按钮时,也踩过这个坑!问题根源其实很简单——你没给cell的滑动范围设个明确的边界,导致它能一直往左滑,不会在按钮完全显示后停下。下面给你具体的解决思路和代码示例:

核心思路

第4种方案的核心是通过UIPanGestureRecognizer监听滑动手势,手动调整cell的frame。我们只需要给cell的x偏移量设置一个最大限制值:当cell向左滑动的距离等于自定义按钮的总宽度时,就禁止继续往左滑。

具体实现(Swift版)

  1. 先定义自定义按钮的总宽度(根据你实际的按钮布局调整数值):
private let customButtonsTotalWidth: CGFloat = 120 // 比如两个按钮加起来120pt
  1. 修改手势处理方法,添加偏移量限制:
@objc private func handleCellPan(_ gesture: UIPanGestureRecognizer) {
    guard let cell = gesture.view as? UITableViewCell else { return }
    let translation = gesture.translation(in: cell)
    
    // 计算目标x坐标,同时限制范围:不能超过0(原位置),也不能小于 -按钮总宽度(完全展开按钮的位置)
    var targetX = cell.frame.origin.x + translation.x
    targetX = max(targetX, -customButtonsTotalWidth)
    targetX = min(targetX, 0)
    
    // 更新cell的位置
    cell.frame.origin.x = targetX
    gesture.setTranslation(.zero, in: cell)
    
    // 手势结束时添加回弹动画,确保cell停在正确位置(要么完全展开,要么回到原位)
    if gesture.state == .ended {
        let shouldKeepOpen = cell.frame.origin.x < -customButtonsTotalWidth / 2
        UIView.animate(withDuration: 0.3) {
            cell.frame.origin.x = shouldKeepOpen ? -self.customButtonsTotalWidth : 0
        }
    }
}
  1. 别忘了在cell复用的时候重置位置,避免复用后保留之前的偏移状态:
override func prepareForReuse() {
    super.prepareForReuse()
    frame.origin.x = 0
}

具体实现(Objective-C版)

如果你用的是OC,逻辑完全一致:

  1. 定义按钮宽度常量:
#define CustomButtonsTotalWidth 120.0f
  1. 手势处理方法:
- (void)handleCellPan:(UIPanGestureRecognizer *)gesture {
    UITableViewCell *cell = (UITableViewCell *)gesture.view;
    CGPoint translation = [gesture translationInView:cell];
    
    CGFloat targetX = cell.frame.origin.x + translation.x;
    targetX = MAX(targetX, -CustomButtonsTotalWidth);
    targetX = MIN(targetX, 0);
    
    cell.frame = CGRectMake(targetX, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height);
    [gesture setTranslation:CGPointZero inView:cell];
    
    if (gesture.state == UIGestureRecognizerStateEnded) {
        BOOL shouldKeepOpen = cell.frame.origin.x < -CustomButtonsTotalWidth / 2;
        [UIView animateWithDuration:0.3 animations:^{
            cell.frame = CGRectMake(shouldKeepOpen ? -CustomButtonsTotalWidth : 0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height);
        }];
    }
}
  1. 重置复用cell的位置:
- (void)prepareForReuse {
    [super prepareForReuse];
    self.frame = CGRectMake(0, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
}

额外注意点

  • 如果你用AutoLayout约束自定义按钮,一定要确保按钮的总宽度是固定值,这样才能准确计算滑动边界。
  • 如果有多个按钮,记得把所有按钮的宽度加起来作为customButtonsTotalWidth的数值。

这样调整后,cell滑动到按钮完全显示的位置就会停止,而且松手后还会有平滑的回弹效果,体验和系统的侧滑删除一致~

内容的提问来源于stack exchange,提问作者dre_84w934

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:12:47