UIWindow 之坑

Context

做一个Pop View有两种方法.

1.用一个UIView盖在当前UIView或者UIWindow的最上面

2.做一个UIWindow,让他变成keyWindow

第一种的好处是…没想到什么特别的好处,大概写起来简单吧.

第二种的好处是,可以扔个ViewController在里面,哈哈哈.

而且第二种,我觉得做起来结构比较清晰.这个Pop View里面做的事情,可以全部封装好,包括显示和消失.
而使用UIView的话,做显示就一定需要把superview作为参数传入,才可以显示,这个还是蛮麻烦的,特别是当我
想做一个全局接收通知,并在UI上显示的东西的时候.由于很难确定当前最顶上的UIView是什么,所以还是UIWindow比较好.

Bug

然而,在水壶架iOS端中,遇到了一个很奇怪的问题.这个问题貌似只在iOS9.3.5之前的系统上出现.对于之后的系统,没有出现这个问题.

从Leancloud的错误报告中看到,这是一个消息传到了空指针的fetal错误.

那就好好找找,为啥变成了空指针吧.

Come on, Where are you

由于一开始这个问题只在9.3.5的手机上出现了,而我和一大票iOS10都没有这个问题.所以我甚至怀疑,这个是手机的问题.

直到我发现所有的老系统,都爆了!我才慌了.

当弹出这个搜索框,再让他消失的时候,做任何的触摸操作,整个app就挂掉了.

所以,问题肯定就在dismiss方法里面!

-(void)disappear
{
    [UIView animateWithDuration:0.3f animations:^{
        self.view.alpha=0;
    } completion:^(BOOL finished) {
        _displayWindows.rootViewController=nil;
            _displayWindows.hidden=YES;
            _displayWindows=nil;
        [[BluetoothManager sharedManager]stopScan];
        [BluetoothManager sharedManager].delegate=nil;
        if (self.delegate) {
            self.delegate=nil;
        }
    }];
}

每次disappear之后,我就中断了整个app,查看他的UI结构,发现有一个不听话的UIWindow还停留在哪儿~

而我明明都把他设置为hidden了,按理说它已经不是keyWindow了~可是他貌似还在.

而且为什么这个东西在iOS 10就没问题了呢~

于是我就去查了查iOS 10的开发这手册,看看他们都做了些什么改变,导致iOS 10不会闪退.

扯远了.

所以说,当这个alert级的UIWindow设置为hidden的时候,没有key window了……

于是乎Touch Event进来的时候,不知道应该给谁了,就爆掉了……

所以所以,得把之前的UIWindow重新恢复key window的地位.

之后改成这样了:

-(void)disappear
{
    [UIView animateWithDuration:0.3f animations:^{
        self.view.alpha=0;
    } completion:^(BOOL finished) {
        _displayWindows.windowLevel=UIWindowLevelNormal;
        _displayWindows.rootViewController=nil;
        [self.view removeFromSuperview];
            [_displayWindows setHidden:YES];
            _displayWindows=nil;
        [[BluetoothManager sharedManager]stopScan];
        [BluetoothManager sharedManager].delegate=nil;
        if (self.delegate) {
            self.delegate=nil;
        }
    }];
    if (_preWindows) {
        [_preWindows makeKeyAndVisible];
        _preWindows=nil;
    }
}

当然这样一改,在show的时候也要做一些修改了~得把之前的UIWindow给记录下来,不然就懵逼咯.