美文网首页
【iOS】修改根控制器后,view的叠加在窗口的问题

【iOS】修改根控制器后,view的叠加在窗口的问题

作者: mapleYe | 来源:发表于2018-08-16 14:52 被阅读0次

    问题描述

    笔者在App登录后,切换RootViewController时,发现window上盖着一层看不见的View。如图所示:


    然后看了window的层级,如图所示:


    发现window除了有一个根控制器TabbarController,还有一个UILayoutContainerView,不难分析出,这就是之前旧的RootVC残留下来,没有释放的View。

    解决方法

    一开始以循环引用的角度入手,但是无奈项目过于庞大,找了非常久仍无法解决问题。最后只好从网上寻求解决方式,最后找到了跟我遇到一样问题的一篇,文章,链接如下:
    http://openfibers.github.io/blog/2015/12/15/window-setrootviewcontroller-view-not-removed-hack/

    文中的解决如下:

    //hack of setRootViewController: old rootViewController's view never removed from window
    - (void)setRootViewController:(UIViewController *)rootViewController
    {
        //remove old rootViewController's sub views
        for (UIView* subView in self.rootViewController.view.subviews)
        {
            [subView removeFromSuperview];
        }
    
        //remove old rootViewController's view
        [self.rootViewController.view removeFromSuperview];
    
        //set new rootViewController
        [super setRootViewController:rootViewController];
    
        //remove empty UILayoutContainerView(s) remaining on root window
        for (UIView *subView in self.subviews)
        {
            if (subView.subviews.count == 0)
            {
                [subView removeFromSuperview];
            }
        }
    }
    

    由于项目是用swift编写的,然后兴冲冲的将以上代码翻译成swift语言,发现怎样都不能满足 subView.subviews.count == 0 。经过打印子view的层级结构,发现UILayoutContainerView仍残余 UITransitionView,那么这个就是 subView.subviews.count == 0 不满足的原因。因此,我们只要耐心等专场动画结束后,再去判断 subView.subviews.count == 0即可。修改后的代码如下:

    class MPWindow: UIWindow {
        override var rootViewController: UIViewController? {
            willSet {
                guard let old = rootViewController else {
                    return
                }
                for sub in old.view.subviews {
                    sub.removeFromSuperview()
                }
                old.view.removeFromSuperview()
            }
            didSet {
                // 延迟2s判断
               DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double((Int64)(2 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in
                    for v in self.subviews {
                        if v.subviews.count == 0 {
                            v.removeFromSuperview()
                        }
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:【iOS】修改根控制器后,view的叠加在窗口的问题

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