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

Xcode 9:如何通过presentViewController移除所有前置视图控制器

解决方案:通过Present并替换根控制器移除所有之前的视图控制器

首先我完全理解你的场景:你把LoginViewController作为子控制器嵌入到了一个父控制器中,现在希望在LoginViewController里presentOtherViewController,同时彻底移除包括父控制器、LoginViewController在内的所有前置视图控制器,确保后续不会再回到原来的层级。

默认情况下,presentViewController:只是在当前控制器栈上叠加新控制器,原有控制器依然驻留在内存中。要彻底清除所有前置控制器,我们需要在present完成后将OtherViewController设为应用的根控制器,这样原来的整个控制器层级会被系统自动销毁(前提是没有其他地方强引用它们)。

方法一:保留Present动画的完整实现

在LoginViewController中使用以下代码:

// 初始化目标控制器
OtherViewController *otherViewController = [[OtherViewController alloc] initWithNibName:nil bundle:nil];

// 先执行present过渡动画,完成后替换根控制器
[self presentViewController:otherViewController animated:YES completion:^{
    // 获取应用主窗口
    UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow;
    // 将目标控制器设为根控制器,原有所有控制器会被销毁
    mainWindow.rootViewController = otherViewController;
}];

这个方法既保留了自然的present过渡动画,又能在动画结束后彻底替换掉原来的控制器层级。

方法二:直接替换根控制器(自定义过渡)

如果不需要present的默认动画,可以直接替换根控制器,还能自定义过渡效果:

OtherViewController *otherViewController = [[OtherViewController alloc] initWithNibName:nil bundle:nil];
UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow;

// 自定义淡入淡出过渡动画
[UIView transitionWithView:mainWindow duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
    mainWindow.rootViewController = otherViewController;
} completion:nil];

关键注意事项

  • 要确保没有全局变量、单例等其他对象强引用原来的父控制器或LoginViewController,否则这些控制器可能无法被正常释放,造成内存泄漏。
  • 在Xcode 9对应的iOS 11环境下,[UIApplication sharedApplication].keyWindow可以正常获取主窗口,无需额外适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:42:02