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

如何在Swift中通过编程模拟惯性滚动?

实现带惯性的模拟滚动事件

要实现和触控板一致的惯性滚动效果,核心是记录手势结束时的速度,然后通过逐帧发送衰减的滚动事件来模拟减速过程,具体步骤如下:

1. 记录手势结束时的滚动速度

在手势识别回调(比如UIPanGestureRecognizer的处理方法)中,捕获手势结束瞬间的速度值,以此作为惯性滚动的初始速度:

// 类级变量存储速度与定时器
private var scrollVelocity: CGFloat = 0.0
private var displayLink: CADisplayLink?

// 手势处理示例
@objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
    switch gesture.state {
    case .changed:
        // 原有实时滚动逻辑
        let delta = gesture.translation(in: view).y
        sendScrollEvent(delta: delta)
        gesture.setTranslation(.zero, in: view)
    case .ended, .cancelled:
        // 记录手势结束时的y轴速度
        scrollVelocity = gesture.velocity(in: view).y
        // 启动惯性滚动
        startInertialScroll()
    default:
        break
    }
}

2. 实现惯性滚动的衰减逻辑

用CADisplayLink(和屏幕刷新率同步,保证流畅性)逐帧生成衰减的滚动事件,模拟自然减速:

private func startInertialScroll() {
    // 先停止之前的定时器,避免重复触发
    displayLink?.invalidate()
    
    displayLink = CADisplayLink(target: self, selector: #selector(updateInertialScroll))
    displayLink?.add(to: .main, forMode: .common)
}

@objc private func updateInertialScroll() {
    // 衰减系数:0.9左右接近系统触控板手感,值越小减速越快
    let dampingFactor: CGFloat = 0.9
    // 最小速度阈值:低于此值停止惯性滚动
    let minVelocityThreshold: CGFloat = 1.0
    
    // 更新速度
    scrollVelocity *= dampingFactor
    
    // 计算本次滚动的delta值,微调0.1系数控制每帧滚动幅度
    let delta = scrollVelocity * 0.1
    
    // 发送滚动事件
    sendScrollEvent(delta: delta)
    
    // 速度低于阈值时停止惯性滚动
    if abs(scrollVelocity) < minVelocityThreshold {
        displayLink?.invalidate()
        displayLink = nil
        scrollVelocity = 0.0
    }
}

// 封装原有滚动事件发送逻辑
private func sendScrollEvent(delta: CGFloat) {
    let event = CGEvent(
        scrollWheelEvent2Source: nil,
        units: .pixel,
        wheelCount: 1,
        wheel1: delta,
        wheel2: 0,
        wheel3: 0
    )
    guard let scrollEvent = event else { return }
    scrollEvent.post(tap: .cghidEventTap)
}

3. 调优细节

  • 衰减系数:可在0.85-0.95区间调整dampingFactor,匹配你想要的惯性手感。
  • 方向适配:如果是横向滚动,只需将y轴速度替换为x轴速度即可。
  • 性能控制:确保CADisplayLink在惯性结束后及时销毁,避免不必要的性能消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:52:33