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

