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

Swift 4:如何在Segue转场动画完成后执行目标视图控制器代码?

嘿,我来帮你搞定这个问题!针对你用CATransition实现自定义转场后,想要在目标视图控制器(VC2)里执行代码的需求,这里有两种靠谱的方案,你可以根据现有代码情况选择:

方案一:用CAAnimation代理精准监听动画完成

这种方法不用大改你现有的代码,只需要给动画加个代理就能捕获结束时机:

  1. 先让你的源VC(VC1)遵循CAAnimationDelegate协议,然后在创建转场动画时设置代理:
class ViewController1: UIViewController, CAAnimationDelegate {
    func goToVC2() {
        let transition = CATransition() 
        transition.duration = 0.5 
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault) 
        transition.type = kCATransitionPush 
        transition.subtype = kCATransitionFromRight
        transition.delegate = self // 给动画加代理
        self.view.window?.layer.add(transition, forKey: nil)
        
        performSegue(withIdentifier: "你的SegueID", sender: nil)
    }
    
    // 动画完成时会触发这个代理方法
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        // 先确保动画是正常完成的
        guard flag else { return }
        // 获取已经跳转过去的VC2,调用它的自定义方法
        if let vc2 = self.presentedViewController as? ViewController2 {
            vc2.doSomethingAfterTransition()
        }
    }
}
  1. 然后在VC2里定义你要执行的方法:
class ViewController2: UIViewController {
    func doSomethingAfterTransition() {
        // 这里写转场完成后要执行的代码,比如更新UI、请求数据等等
        print("转场完成啦,开始执行VC2的专属逻辑~")
    }
}
方案二:改用UIKit标准自定义转场(更规范)

如果想让你的转场逻辑更贴合UIKit的设计,推荐用UIViewControllerTransitioningDelegate,这种方式扩展性更强,后续加返回动画也很方便:

  1. 在VC1里,手动实例化VC2并设置转场代理:
class ViewController1: UIViewController {
    func navigateToVC2() {
        guard let vc2 = storyboard?.instantiateViewController(withIdentifier: "ViewController2") as? ViewController2 else { return }
        vc2.transitioningDelegate = self
        vc2.modalPresentationStyle = .fullScreen // 根据你的需求设置展示样式
        present(vc2, animated: true, completion: nil)
    }
}

// 让VC1遵循转场代理协议,提供自定义动画
extension ViewController1: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomPushAnimator() // 自定义动画类
    }
}
  1. 创建一个自定义动画类,实现转场动画和完成回调:
class CustomPushAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    // 动画时长和你之前设置的一致
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let container = transitionContext.containerView
        guard let toVC = transitionContext.viewController(forKey: .to) else { return }
        
        // 把VC2的视图先放到屏幕右侧
        container.addSubview(toVC.view)
        toVC.view.frame = container.frame.offsetBy(dx: container.frame.width, dy: 0)
        
        // 执行平移动画,模拟push效果
        UIView.animate(withDuration: transitionDuration(using: transitionContext), options: .curveEaseInOut) {
            toVC.view.frame = container.frame
        } completion: { finished in
            // 标记转场完成,然后调用VC2的方法
            transitionContext.completeTransition(finished)
            guard finished, let vc2 = toVC as? ViewController2 else { return }
            vc2.doSomethingAfterTransition()
        }
    }
}
  1. 同样在VC2里定义doSomethingAfterTransition方法,内容和方案一一致就行。

小提醒

尽量别用DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)这种延迟执行的方式,因为动画实际完成时间可能受系统负载影响,会有误差,用代理或者标准转场的回调才是精准的做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:55:05