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

UIPercentDrivenInteractiveTransition慢速平移跳帧问题的解决方法

解决UIPercentDrivenInteractiveTransition慢速平移时的跳帧问题

你遇到的慢速平移时视图左右跳帧的问题,核心原因是百分比计算未做范围限制,加上手势触发时没有过滤无效的平移方向,导致交互过渡出现反向或异常的动画更新。咱们一步步来修复:

1. 限制百分比的有效范围

当前代码中,当用户向左滑动时translation.x会变成负数,计算出的percentage也会为负,调用update(percentage)会让视图反向移动,直接造成跳动。我们需要把百分比钳制在0~1的区间内:

修改didPan里的百分比计算逻辑:

let translation = recognizer.translation(in: viewController.view)
// 强制百分比在0到1之间,避免反向或过度动画
let percentage = max(0, min(translation.x / viewController.view.frame.size.width, 1))

2. 只允许向右平移触发dismiss

在手势开始阶段,先判断平移方向,只有向右滑动(x方向速度为正)才启动交互dismiss,避免无效的交互触发:

在.began状态分支添加判断:

case .began:
    let velocity = recognizer.velocity(in: viewController.view)
    // 仅向右滑动时才允许触发dismiss
    guard velocity.x > 0 else {
        enabled = false
        break
    }
    enabled = true
    viewController.dismiss(animated: true, completion: nil)
    break

3. 优化动画器的曲线匹配

你的动画器使用了.curveEaseIn曲线,但交互过渡时更适合用线性曲线,避免动画速度和手势拖动速度不匹配导致的跳帧:

修改动画器的动画选项:

UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0.0, options: .curveLinear, animations: {
    fromVC.view.frame = endFrame
    toVC.overlay.alpha = 0
}, completion: { _ in
    if transitionContext.transitionWasCancelled {
        transitionContext.completeTransition(false)
    } else {
        transitionContext.completeTransition(true)
    }
})

4. 重置手势的累积偏移(可选优化)

手势的translation值会在多次触发后累积,可能导致下次手势的初始计算异常,在手势结束或取消时重置偏移量:

在.ended、.cancelled等状态分支添加:

recognizer.setTranslation(.zero, in: viewController.view)

完整修改后的didPan方法

@objc func didPan(with recognizer: UIPanGestureRecognizer) {
    let translation = recognizer.translation(in: viewController.view)
    let percentage = max(0, min(translation.x / viewController.view.frame.size.width, 1))
    print(percentage)
    switch recognizer.state {
    case .began:
        let velocity = recognizer.velocity(in: viewController.view)
        guard velocity.x > 0 else {
            enabled = false
            break
        }
        enabled = true
        viewController.dismiss(animated: true, completion: nil)
        break
    case .changed:
        update(percentage)
        break
    case .ended:
        completionSpeed = 0.3
        recognizer.setTranslation(.zero, in: viewController.view)
        if percentage > 0.5 {
            finish()
        } else {
            cancel()
        }
        enabled = false
        break
    case .cancelled:
        recognizer.setTranslation(.zero, in: viewController.view)
        cancel()
        enabled = false
        break
    default:
        recognizer.setTranslation(.zero, in: viewController.view)
        cancel()
        enabled = false
        break
    }
}

这些修改通过限制有效交互范围、匹配动画与手势的速度逻辑,应该能彻底解决慢速平移时的跳帧问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:01:26