首页 > 代码库 > (转摘+修改) 深入理解 UIWindow & UIWindowLevel

(转摘+修改) 深入理解 UIWindow & UIWindowLevel

转载于:  http://www.cnblogs.com/smileEvday/archive/2012/03/27/2420362.html

 


一、UIWindow是一种特殊的UIView,通常在一个程序中只会有一个UIWindow,但可以手动创建多个UIWindow,同时加到程序里面。UIWindow在程序中主要起到三个作用:

  1、作为容器,包含app所要显示的所有视图

  2、传递触摸消息到程序中view和其他对象

  3、与UIViewController协同工作,方便完成设备方向旋转的支持

二、通常我们可以采取两种方法将view添加到UIWindow中:

  1、addSubview

  直接将view通过addSubview方式添加到window中,程序负责维护view的生命周期以及刷新,但是并不会为去理会view对应的ViewController,因此采用这种方法将view添加到window以后,我们还要保持view对应的ViewController的有效性,不能过早释放。(需要自己维护UIViewController的生命周期)

  2、rootViewController

  rootViewController时UIWindow的一个遍历方法,通过设置该属性为要添加view对应的ViewController,UIWindow将会自动将其view添加到当前window中,同时负责ViewController和view的生命周期的维护,防止其过早释放

三、WindowLevel

  UIWindow在显示的时候会根据UIWindowLevel进行排序的,即Level高的将排在所有Level比他低的层级的前面。下面我们来看UIWindowLevel的定义:

    const UIWindowLevel UIWindowLevelNormal;
    const UIWindowLevel UIWindowLevelAlert;
    const UIWindowLevel UIWindowLevelStatusBar;
    typedef CGFloat UIWindowLevel;

  IOS系统中定义了三个window层级,其中每一个层级又可以分好多子层级(从UIWindow的头文件中可以看到成员变量CGFloat _windowSublevel;),不过系统并没有把则个属性开出来。UIWindow的默认级别是UIWindowLevelNormal,我们打印输出这三个level的值分别如下:

2012-03-27 22:46:08.752 UIViewSample[395:f803] Normal window level: 0.000000
2012-03-27 22:46:08.754 UIViewSample[395:f803] Alert window level: 2000.000000
2012-03-27 22:46:08.755 UIViewSample[395:f803] Status window level: 1000.000000

  这样印证了他们级别的高低顺序从小到大为Normal < StatusBar < Alert,下面请看小的测试代码:

 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 2 { 3 // Override point for customization after application launch. 4 _normalWindow = [[UIWindow alloc] initWithFrame:CGRectInset([UIScreen mainScreen].bounds, 10.0f, 10.0f)]; 5 _normalWindow.backgroundColor = [UIColor blueColor]; 6 _normalWindow.windowLevel = UIWindowLevelNormal; 7 [_normalWindow makeKeyAndVisible]; 8  9 _statusBarWindow = [[UIWindow alloc] initWithFrame:CGRectInset([UIScreen mainScreen].bounds, 20.0f, 20.0f)];10 _statusBarWindow.backgroundColor = [UIColor yellowColor];11 _statusBarWindow.windowLevel = UIWindowLevelStatusBar;12 [_statusBarWindow makeKeyAndVisible];13 14 _alertWindow = [[UIWindow alloc] initWithFrame:CGRectInset([UIScreen mainScreen].bounds, 40.0f, 40.0f)];15 _alertWindow.backgroundColor = [UIColor redColor];16 _alertWindow.windowLevel = UIWindowLevelAlert;17 [_alertWindow makeKeyAndVisible];18 19 NSLog(@"Normal Window Level : %f" ,UIWindowLevelNormal);20 NSLog(@"Statusbar Window Level : %f",UIWindowLevelStatusBar);21 NSLog(@"Alert Window Level : %f",UIWindowLevelAlert);22 23 return YES;24 }

 总结: WindowLevel高的覆盖WindowLevel低的,若WindowLevel相同,则先创建的覆盖后创建的。

ps:

一、

(由于现在Xcode5新建工程时自动选择ARC,所以应当使normalWindow,statusBarWindos,alertWindos 为AppDelegate的属性或成员变量,不然当didFinishLaunchingWithOptions

执行完,相应的局部变量windows也释放了,并不会在屏幕上显示出来。)

 

二、当你使用Stroyboard来设计你的UI界面时,你不需要明确的创建,配置和加载你的Window。系统默认为你做了三件事:

1.Instantiates a window.(实例化一个window)

2、Loads the main storyboard and instantiates its initial view controller.(加载main storyboard,并实例化其 initial View Controller)

3、Assigns the new view controller to the window’s rootViewController property and then makes the window visible.(将2中实例化的View Controller 赋于 1中window的rootViewController属性)

(转摘+修改) 深入理解 UIWindow & UIWindowLevel