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

如何实现导航视图控制器滑动时的即时转场(避免转场取消)

嘿,我完全get你的需求——你想保留导航控制器的滑动返回和顶部返回按钮功能,但烦透了用户滑到一半又取消、停在当前页面的情况,而且不想粗暴地禁用滑动返回对吧?这有两个优雅的实现方案,能让转场一旦触发就直接完成:

方案一:强制完成交互式滑动转场(保留系统滑动动画)

这个方案会保留系统原生的滑动返回动画,但只要用户开始滑动,就强制转场完成,不允许中途取消。核心是通过UINavigationControllerDelegate和UIPercentDrivenInteractiveTransition来控制转场进度:

class CustomNavigationController: UINavigationController, UINavigationControllerDelegate {
    private var interactiveTransition: UIPercentDrivenInteractiveTransition?

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }

    // 处理交互式转场的控制器
    func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        // 一旦滑动转场被触发,直接强制完成
        interactiveTransition?.finishInteractiveTransition()
        return interactiveTransition
    }

    // 配置转场动画控制器
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        // 只有返回操作时才初始化交互式转场
        if operation == .pop {
            interactiveTransition = UIPercentDrivenInteractiveTransition()
            interactiveTransition?.completionSpeed = 1.0 // 确保动画全速完成
        } else {
            interactiveTransition = nil
        }
        return nil // 使用系统默认的返回动画
    }
}

说明:当用户触发滑动返回手势时,我们直接调用finishInteractiveTransition(),让系统立刻完成整个转场动画,不管用户有没有继续滑动,这样就不会出现中途停住的情况。

方案二:拦截滑动手势,直接触发普通返回

如果你不需要保留滑动过程中的交互感,只想让滑动手势直接触发返回操作,可以拦截系统的滑动返回手势,一旦检测到手势开始,就直接调用普通的popViewController:

class YourContentViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 获取系统自带的滑动返回手势
        guard let popGesture = navigationController?.interactivePopGestureRecognizer else { return }
        popGesture.delegate = self
    }
}

extension YourContentViewController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        // 确保当前不是根控制器,避免崩溃
        guard navigationController?.viewControllers.count ?? 0 > 1 else {
            return false
        }
        
        // 直接触发返回操作
        navigationController?.popViewController(animated: true)
        return false // 阻止系统的交互式手势继续执行
    }
}

说明:这个方案相当于把滑动手势变成了一个“触发式”的按钮,用户只要开始滑动,就立刻执行普通的返回动画,完全跳过系统的交互式转场逻辑,自然也就不存在中途取消的问题。

你可以根据自己的需求选择:如果想保留滑动的动画过程但不允许取消,方案一更合适;如果追求简单直接,方案二上手更快。

内容的提问来源于stack exchange,提问作者Adam S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:39:49