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
相关产品推荐
相关产品推荐

