随着业务越来越复杂,越来越繁多,甚至与web共舞
一键返回首页的情况就很常见了
最简单的方式是直接重新设置AppDelegate.window.rootViewController
但是这样做有小伙伴发现如果页面栈存在present的情况,会出现部分页面无法被释放,从而导致内存泄漏
所以,在页面栈繁杂,弹出页面方式奇奇怪怪的情况下,还能有条不紊的返回APP首页,使我们当下的需求
那么,如何才能安全的、不出错的返回首页呢,并且最好能保证体验良好?
答案是:原路返回,怎么出去就怎么回来
思路及代码实现
1、获取到当前的根视图,如果是UITabBarController
做特殊处理
UIWindow *window = [(AppDelegate *)[UIApplication sharedApplication].delegate window];
UIViewController *rootController = [window rootViewController];
if ([rootController isKindOfClass:[UITabBarController class]]) {
rootController = [(UITabBarController *)rootController selectedViewController];
}
UIViewController *presentedController = rootController;
2、找到所有的presentedViewController
,包括UIViewController
和UINavigationController
NSMutableArray<UIViewController *> *presentedControllerArray = [[NSMutableArray alloc] init];
while (presentedController.presentedViewController) {
[presentedControllerArray addObject:presentedController.presentedViewController];
presentedController = presentedController.presentedViewController;
}
3、将所有找到的vc进行递归dismiss操作或popToRoot
if (presentedControllerArray.count > 0) {
//把所有presented的controller都dismiss掉
[self dismissControllers:presentedControllerArray topIndex:presentedControllerArray.count - 1 completion:^{
[self popToRootViewControllerFrom:rootController];
}];
} else {
[self popToRootViewControllerFrom:rootController];
}
递归方法封装
- (void)dismissControllers:(NSArray<UIViewController *> *)presentedControllerArray topIndex:(NSInteger)index completion:(void(^)(void))completion
{
if (index < 0) {
completion();
} else {
[presentedControllerArray[index] dismissViewControllerAnimated:NO completion:^{
[self dismissControllers:presentedControllerArray topIndex:index - 1 completion:completion];
}];
}
}
- (void)popToRootViewControllerFrom:(UIViewController *)fromViewController
{
if ([fromViewController isKindOfClass:[UINavigationController class]]) {
[(UINavigationController *)fromViewController popToRootViewControllerAnimated:NO];
}
if (fromViewController.navigationController) {
[fromViewController.navigationController popToRootViewControllerAnimated:NO];
}
}
这里有人可能会问,为什么不使用setRootViewController的方式返回?
如果有present的vc弹出,在setRoot的时候会造成一定的内存泄漏,如果流程多来几次,有可能产生很多不可预期的问题,所以,原路返回是最为稳妥和安全的一种方式。
欢迎大家分享自己的返回首页方案
借鉴:https://blog.csdn.net/yinyignfenlei/article/details/86167245
网友评论