UIWindow的windowLevel属性

UIWindow是我们必不可少的类,可能使用的较少,但是一个项目中少它不行,因为它是我们最顶层的界面容器,我们自己的相关的ViewController都要最终放到window.rootController中。一班情况UIWindow作为顶层容器的存在。
介绍下UIWindow的一个属性,windowLevel。
苹果文档中windowLevel有三种形式,并且是CGFloat类型的

UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar __TVOS_PROHIBITED;

它们的值可以分别通过打印来验证

NSLog(@"%f  %f  %f",UIWindowLevelNormal,UIWindowLevelAlert,UIWindowLevelStatusBar);

0.000000 2000.000000 1000.000000

键盘Window:经常用的弹出键盘,其实也是一个UIWindow,苹果没有列出,也没有相关的公开API调用。但是我们可以利用模拟器跑demo弹出键盘时,打开xcode的图层查看器,你会发现有三个Window层级(其实还有一个statusBarWindow看不到),UIwindow是我们 keywindow,UItextEffectsWindow(文本效果窗口,如毛玻璃效果),UIRemoteKeyboardWindow(这个类是调用不到)。它们的windowLevel分别是

0.000000 1.000000 1000000.000000

你没看错,键盘Window的WindowLevel是100万级,最高级。

ps:UItextEffectsWindow 是iOS8 新特性,部分说法,键盘Window是在UItextEffectsWindow上,说法是不对的,即使不弹出键盘,也会有 UItextEffectsWindow,只是在该Windows上还有个view来标识键盘位置而已,UItextEffectsWindow和UIRemoteKeyboardWindow是两个window。

UIwindow都是继承自UIview的 你也可以自定义视图addsubview到键盘的window上。

这个属性是干啥的,

UIWindow的windowLevel属性_第1张图片
image

也就是可以通过这个属性来判断是不是优先显示UIWindow。默认的window的windowLevel是UIWindowLevelNormal,也就是0;
下面我们通过小Demo进行验证
1、首先验证苹果头文件中的UIWindow的windowLevel是多少

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSLog(@"UIWindowLevelNormal = %f  UIWindowLevelAlert = %f  UIWindowLevelStatusBar = %f  appDelegate.window.windowLevel = %f",UIWindowLevelNormal,UIWindowLevelAlert,UIWindowLevelStatusBar,appDelegate.window.windowLevel);

验证结果

UIWindowLevelNormal = 0.000000  
UIWindowLevelAlert = 2000.000000  
UIWindowLevelStatusBar = 1000.000000 
appDelegate.window.windowLevel = 0.000000

2、验证系统通过UIWindow的windowLevel大小不同优先显示不同的UIWindow
需要注意的是,UIWindow的创建和UIView不同,UIWindow一旦被创建他就会添加到整个界面上。
如果你创建的UIWindow没有显示,请参考:
http://www.jianshu.com/p/75befce85623

创建不同的windowLevel查看相关的效果,代码如下

#import "ViewController.h"
@interface ViewController ()
// 创建属性@property (nonatomic, strong)UIWindow *myWindow1;
@property (nonatomic, strong)UIWindow *myWindow2;
@property (nonatomic, strong)UIWindow *myWindow3;
@end
- (void)viewDidLoad {
    [super viewDidLoad];  
   // Do any additional setup after loading the view, typically from a nib.   
   // 创建测试按钮    
  UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeSystem];  
  tempBtn.frame = CGRectMake(100, 100, 100, 100);    
  tempBtn.backgroundColor = [UIColor cyanColor];  
  // 通过按钮的点击事件生成不同windowLevel级别的window 
  [tempBtn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];    
  [self.view addSubview:tempBtn];}

按钮的单击事件调用test1
创建一个比默认window的windowLevel大的window来看一下什么效果,效果是会盖在原来的window上面

/** *  这个方法证明两个问题 
*1、创建 window 不用添加到任何的控件上面,直接创建完毕就能添加
*2、创建一个比默认window的windowLevel大的window来看一下什么效果,效果是会盖在原来的window上面 */
- (void)test1{ 
    // 创建window   
    if (self.myWindow1 == nil) {  
        self.myWindow1 = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
        UIButton *windowBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 
        [windowBtn setTitle:@"window1点我隐藏" forState:UIControlStateNormal]; 
        windowBtn.backgroundColor = [UIColor redColor]; 
        windowBtn.frame = CGRectMake(100, 300, 100, 100);
        [windowBtn addTarget:self action:@selector(clickWindowBtn:) forControlEvents:UIControlEventTouchUpInside];
        [self.myWindow1 addSubview:windowBtn]; 
    }    
    // 设置window的颜色,这里设置成半透明的,方便查看window的层级关系    
   self.myWindow1.backgroundColor = [UIColor colorWithRed:0.00f green:1.00f blue:0.01f alpha:0.50f]; 
   // 设置 window 的 windowLevel    
   self.myWindow1.windowLevel = 100; 
   self.myWindow1.hidden = NO;
}

效果图:

UIWindow的windowLevel属性_第2张图片
image

按钮的单击事件调用test2
创建一个和默认window的windowLevel一样大的window来看一下什么效果,效果是会盖在原来的window上面

/** *  这个方法证明两个问题 
*1、创建 window 不用添加到任何的控件上面,直接创建完毕就能添加 
*2、创建一个和默认window的windowLevel一样大的window来看一下什么效果,效果是会盖在原来的window上面 */
- (void)test2{ 
   // 创建window   
 if (self.myWindow2 == nil) {
        self.myWindow2 = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];  
        UIButton *windowBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
        [windowBtn setTitle:@"window2点我隐藏" forState:UIControlStateNormal];  
        windowBtn.backgroundColor = [UIColor greenColor];  
        windowBtn.frame = CGRectMake(100, 300, 200, 100);  
        [windowBtn addTarget:self action:@selector(clickWindow2Btn:) forControlEvents:UIControlEventTouchUpInside];
        [self.myWindow2 addSubview:windowBtn];  
   }    
   // 设置window的颜色,这里设置成半透明的,方便查看window的层级关系 
   self.myWindow2.backgroundColor = [UIColor colorWithRed:0.91f green:0.13f blue:0.13f alpha:0.50f];  
   // 设置 window 的 windowLevel,设置的和当前存在的window一样 
   self.myWindow2.windowLevel = self.view.window.windowLevel; 
   self.myWindow2.hidden = NO;  
   [self.myWindow2 makeKeyAndVisible];
}

效果图

UIWindow的windowLevel属性_第3张图片
image

按钮的单击事件调用test3
创建一个和默认window的windowLevel一样大的window来看一下什么效果,效果是会在在原来的window下面

/** *  这个方法证明两个问题 
*1、创建 window 不用添加到任何的控件上面,直接创建完毕就能添加 
*2、创建一个和默认window的windowLevel一样大的window来看一下什么效果,效果是会在在原来的window下面 */ 
- (void)test3{
    // 为了展示相关的效果,把当前的window的透明度设置为0.5  
  self.view.window.alpha = 0.5;    
   // 创建window  
  if (self.myWindow3 == nil) {  
      self.myWindow3 = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
   }    
  // 设置window的颜色,这里设置成半透明的,方便查看window的层级关系    
   self.myWindow3.backgroundColor = [UIColor blueColor];  
   // 设置 window 的 windowLevel,设置的比当前存在的window的小 
   self.myWindow3.windowLevel = -1; 
   self.myWindow3.hidden = NO;  
   [self.myWindow3 makeKeyAndVisible];
}

执行效果:

UIWindow的windowLevel属性_第4张图片
image

调用完test方法可以查看当前一共有几个window,并且查看当前的测试window有没有实例化成功,所有的实例化的window并且声明周期够长,可以在[UIApplication sharedApplication].windows找到。

// 查看当前所有的window
NSLog(@"当前所有的window = %@ \nself.myWindow1 = %@",[UIApplication sharedApplication].windows,self.myWindow3);

总结如下:

  • 1、UIWindowLevel的值不仅仅只有UIWindowLevelNormal、UIWindowLevelAlert、UIWindowLevelStatusBar 这三个,可以通过test3看出,只要你想可以是随意值,负数都可以。
  • 2、UIWindow的显示的确可以通过UIWindowLevel来区分优先级,所有的window都会被加在界面上,只不过会通过优先级罗列起来,UIWindowLevel大的在上面显示,UIWindowLevel小的在下面显示。
  • 3、UIWindowLevel优先级相等的情况下,看谁后实例化了,谁后实例化谁先显示

转载文章:https://blog.csdn.net/u011363981/article/details/74504641

你可能感兴趣的:(UIWindow的windowLevel属性)