Swift中如何实现滑动过程中按距离重复执行操作?
解决滑动过程中重复执行操作的问题
UISwipeGestureRecognizer本身是一次性触发的,只有当滑动动作完成时才会调用一次处理方法,完全没法满足你“滑动过程中每1毫米重复执行操作”的需求。要实现这个效果,你需要换成UIPanGestureRecognizer——它能实时跟踪手指滑动的全过程,包括移动中的位置变化。
具体实现步骤
1. 替换手势类型
移除原来的Swipe手势,改用Pan手势:
// 先移除原有Swipe手势(如果已经添加) // self.removeGestureRecognizer(swipeLeft) // self.removeGestureRecognizer(swipeRight) // 添加Pan手势 let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture)) self.addGestureRecognizer(panGesture)
2. 添加状态跟踪变量
需要几个变量来记录滑动的关键状态:
// 记录手势开始时的初始触摸位置 private var initialTouchPoint: CGPoint = .zero // 记录上次触发操作时的位置,防止短距离内重复触发 private var lastTriggerPoint: CGPoint = .zero // 计算1毫米对应的屏幕像素值(适配不同密度的屏幕) private let mmToPixel: CGFloat = UIScreen.main.nativeScale / 25.4
3. 实现Pan手势处理逻辑
核心是在手势的.changed状态中实时计算滑动距离,达到1毫米阈值就执行操作:
@objc func handlePanGesture(sender: UIPanGestureRecognizer) { let currentPoint = sender.location(in: self) switch sender.state { case .began: // 手势启动时初始化位置记录 initialTouchPoint = currentPoint lastTriggerPoint = currentPoint case .changed: // 计算当前与上次触发位置的横向滑动距离 let horizontalDistance = currentPoint.x - lastTriggerPoint.x // 左滑判断:距离小于负的1毫米像素值 if horizontalDistance <= -mmToPixel { handleLeftSwipeAction() // 更新触发位置,避免重复触发 lastTriggerPoint.x = currentPoint.x } // 右滑判断:距离大于1毫米像素值 else if horizontalDistance >= mmToPixel { handleRightSwipeAction() lastTriggerPoint.x = currentPoint.x } case .ended, .cancelled, .failed: // 手势结束后重置状态 initialTouchPoint = .zero lastTriggerPoint = .zero default: break } } // 封装左滑操作逻辑(复用你原来的代码) private func handleLeftSwipeAction() { if nextImage >= imagesCount - 4 { nextImage = 0 } else { nextImage += 4 } // 这里记得添加更新UI的代码,比如刷新图片显示 // updateImageDisplay() } // 封装右滑操作逻辑 private func handleRightSwipeAction() { if nextImage <= 0 { nextImage = imagesCount - 4 } else { nextImage -= 4 } // 更新UI // updateImageDisplay() }
关键说明
- UIPanGestureRecognizer:区别于Swipe手势的一次性触发,它会在手指滑动过程中持续触发
.changed状态,让我们能实时响应滑动距离变化。 - 毫米转像素:不同设备的屏幕像素密度不同,通过
UIScreen.main.nativeScale(原生像素密度)除以25.4(1英寸=25.4毫米),可以准确计算出1毫米对应的屏幕像素数,保证在不同设备上的滑动距离一致。 - 防重复触发:通过
lastTriggerPoint记录每次触发操作的位置,只有当滑动距离再次达到1毫米阈值时才会执行下一次操作,避免短距离内多次重复触发。
内容的提问来源于stack exchange,提问作者Vadim
相关产品推荐
相关产品推荐

