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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:06:21