美文网首页
iOS 一键返回首页

iOS 一键返回首页

作者: ZT_Story | 来源:发表于2019-12-27 09:30 被阅读0次

    随着业务越来越复杂,越来越繁多,甚至与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,包括UIViewControllerUINavigationController

    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

    相关文章

      网友评论

          本文标题:iOS 一键返回首页

          本文链接:https://www.haomeiwen.com/subject/wgakoctx.html