如何禁用UITableView中UITableViewCell侧滑删除时的回弹效果?
解决UITableViewCell侧滑自定义按钮时无法停止滑动的问题
嘿,我之前用那个教程的第4种方案实现自定义侧滑按钮时,也踩过这个坑!问题根源其实很简单——你没给cell的滑动范围设个明确的边界,导致它能一直往左滑,不会在按钮完全显示后停下。下面给你具体的解决思路和代码示例:
核心思路
第4种方案的核心是通过UIPanGestureRecognizer监听滑动手势,手动调整cell的frame。我们只需要给cell的x偏移量设置一个最大限制值:当cell向左滑动的距离等于自定义按钮的总宽度时,就禁止继续往左滑。
具体实现(Swift版)
- 先定义自定义按钮的总宽度(根据你实际的按钮布局调整数值):
private let customButtonsTotalWidth: CGFloat = 120 // 比如两个按钮加起来120pt
- 修改手势处理方法,添加偏移量限制:
@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 } } }
- 别忘了在cell复用的时候重置位置,避免复用后保留之前的偏移状态:
override func prepareForReuse() { super.prepareForReuse() frame.origin.x = 0 }
具体实现(Objective-C版)
如果你用的是OC,逻辑完全一致:
- 定义按钮宽度常量:
#define CustomButtonsTotalWidth 120.0f
- 手势处理方法:
- (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); }]; } }
- 重置复用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
相关产品推荐
相关产品推荐

