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

如何在Present新ViewController时隐藏当前VC并保留返回功能

解决方案

方法1:临时隐藏VC2视图并在转场完成后恢复

通过在present VC3前隐藏VC2的视图,再监听转场完成事件恢复视图显示,既能避免过渡动画中看到VC2,也不影响dismiss后回到VC2。

代码示例:

class VC2: UIViewController, UIViewControllerTransitioningDelegate {
    private var needRestoreView = false
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // 隐藏当前视图
        view.isHidden = true
        needRestoreView = true
        
        let vc3 = VC3()
        vc3.transitioningDelegate = self
        present(vc3, animated: true)
    }
    
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        let presentationController = CustomPresentationController(presentedViewController: presented, presenting: presenting)
        presentationController.delegate = self
        return presentationController
    }
}

// 自定义PresentationController监听转场完成
class CustomPresentationController: UIPresentationController {
    override func presentationTransitionDidEnd(_ completed: Bool) {
        super.presentationTransitionDidEnd(completed)
        guard let vc2 = presentingViewController as? VC2 else { return }
        if vc2.needRestoreView && completed {
            vc2.view.isHidden = false
            vc2.needRestoreView = false
        }
    }
}

方法2:设置VC2背景透明+VC3全屏模态

将VC2的背景设为透明,同时让VC3以全屏模态方式展示,这样过渡动画期间VC2的透明背景不会被感知,dismiss后VC2的内容可正常显示。

代码示例:

class VC2: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置VC2背景为透明
        view.backgroundColor = .clear
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        let vc3 = VC3()
        // 配置VC3为全屏模态
        vc3.modalPresentationStyle = .fullScreen
        present(vc3, animated: true)
    }
}

注意:该方法仅适用于VC3需要全屏展示的场景,非全屏VC3需配合自定义转场确保覆盖整个屏幕。

方法3:延迟present至VC2显示动画完成

若VC2本身是通过push/present跳转而来,其viewWillAppear/viewDidAppear会在自身显示动画未完成时触发,导致两个动画叠加。延迟present操作可避免这一问题。

代码示例:

class VC2: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // 延迟0.3秒(匹配系统默认动画时长)执行present
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            let vc3 = VC3()
            self.present(vc3, animated: true)
        }
    }
}

缺点是会有短暂的VC2显示时间,适合对过渡时机要求不严格的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:05:24