转自:http://www.cnblogs.com/smileEvday/archive/2012/11/16/UIWindow.html

  每一个IOS程序都有一个UIWindow,在我们通过模板简历工程的时候,xcode会自动帮我们生成一个window,然后让它变成keyWindow并显示出来。这一切都来的那么自然,以至于我们大部分时候都忽略了自己也是可以创建UIWindow对象。

  通常在我们需要自定义UIAlertView的时候(IOS 5.0以前AlertView的背景样式等都不能换)我们可以使用UIWindow来实现(设置windowLevel为Alert级别),网上有很多例子,这里就不详细说了。

  我的上一篇文章UIWindowLevel详解,中讲到了关于Windowlevel的东西,当时还只是看了看文档,知道有这么一回儿事。今天刚好遇到这块儿的问题,就顺便仔细看了一下UIWindow方面的东西,主要包括:WindowLevel以及keyWindow两个方面。

一、UIWindowLevel

  我们都知道UIWindow有三个层级,分别是Normal,StatusBar,Alert。打印输出他们三个这三个层级的值我们发现从左到右依次是0,1000,2000,也就是说Normal级别是最低的,StatusBar处于中等水平,Alert级别最高。而通常我们的程序的界面都是处于Normal这个级别上的,系统顶部的状态栏应该是处于StatusBar级别,UIActionSheet和UIAlertView这些通常都是用来中断正常流程,提醒用户等操作,因此位于Alert级别。

  上一篇文章中我也提到了一个猜想,既然三个级别的值之间相差1000,而且我们细心的话查看UIWindow的头文件就会发现有一个实例变量_windowSublevel,那我们就可以定义很多中间级别的Window。例如可以自定义比系统UIAlertView级别低一点儿的window。于是写了一个小demo,通过打印发现系统的UIAlertView的级别是1996,而与此同时UIActionSheet的级别是2001,这样也验证了subLevel的确存在。

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Alert View"
message:@"Hello Wolrd, i'm AlertView!!!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:@"Cancel", nil];
[alertView show];
[alertView release]; UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"ActionSheet"
delegate:nil
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Don't do that!"
otherButtonTitles:@"Hello Wolrd", nil];
[actionSheet showInView:self.view];
[actionSheet release];

  下面是程序运行截图:

  根据window显示级别优先的原则,级别高的会显示在上面,级别低的在下面,我们程序正常显示的view位于最底层,至于具体怎样获取UIAlertView和UIActionSheet的level,我会在下面第二部分keyWindow中介绍并给出相应的代码。

二、KeyWindow

  什么是keyWindow,官方文档中是这样解释的"The key window is the one that is designated to receive keyboard and other non-touch related events. Only one window at a time may be the key window." 翻译过来就是说,keyWindow是指定的用来接收键盘以及非触摸类的消息,而且程序中每一个时刻只能有一个window是keyWindow。

  下面我们写个简单的例子看看非keyWindow能不能接受键盘消息和触摸消息,程序中我们在view中添加一个UITextField,然后新建一个alert级别的window,然后通过makeKeyAndVisible让它变成keyWindow并显示出来。代码如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[SvUIWindowViewController alloc] initWithNibName:@"SvUIWindowViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible]; UIWindow *window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 80, 320, 320)];
window1.backgroundColor = [UIColor redColor];
window1.windowLevel = UIWindowLevelAlert;
[window1 makeKeyAndVisible]; return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. [self registerObserver]; // add a textfield
UITextField *filed = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 320, 60)];
filed.placeholder = @"Input something here";
filed.clearsOnBeginEditing = YES;
filed.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:filed];
[filed release];
}

  运行截图如下:

  从图中可以看出,虽然我们自己新建了一个然后设置为keyWindow并显示,但是点击程序中默认window上添加的textField还是可以唤出键盘,而且还可以正常接受键盘输入,只是键盘被挡住了,说明非keyWindow也是可以接受键盘消息,这一点和文档上说的不太一样。

  观察UIWindow的文档,我们可以发现里面有四个关于window变化的通知:

  UIWindowDidBecomeVisibleNotification

  UIWindowDidBecomeHiddenNotification

  UIWindowDidBecomeKeyNotification

  UIWindowDidResignKeyNotification

  这四个通知对象中的object都代表当前已显示(隐藏),已变成keyWindow(非keyWindow)的window对象,其中的userInfo则是空的。于是我们可以注册这个四个消息,再打印信息来观察keyWindow的变化以及window的显示,隐藏的变动。

  代码如下:

SvUIWindowViewController.m

  a、当我们打开viewDidAppear中“[self presentAlertView];”的时候,控制台输出如下

  根据打印的信息我们可以看出流程如下:

  1、程序默认的window先显示出来

  2、默认的window再变成keyWindow

  3、AlertView的window显示出来

  4、默认的window变成非keyWindow

  5、最终AlertView的window变成keyWindow

  总体来说就是“要想当老大(keyWindow),先从小弟(非keyWindow)开始混起” 而且根据打印的信息我们同事可以知道默认的window的level是0,即normal级别;AlertView的window的level是1996,比Alert级别稍微低了一点儿。

  b、当我们打开viewDidAppear中“[self presentActionSheet];”的时候,控制台输出如下:  

  keyWindow的变化和window的显示和上面的流程一样,同时我们可以看出ActionSheet的window的level是2001。

  c、接着上一步,我们点击弹出ActionSheet的cancel的时候,控制台输出如下:

  我们看出流程如下:

  1、首先ActionSheet的window变成非keyWindow

  2、程序默认的window变成keyWindow

  3、ActionSheet的window在隐藏掉

  总体就是“想隐居幕后可以,但得先交出权利”。

UIWindow的一点儿思考的更多相关文章

  1. babel和postcss引起的一点儿思考

    写es6,一般都会用到babel,它能把es6转为更好的es5,而es5可以直接在浏览器上运行.postcss是css界的babel,它可以把css转为更好的css,比如autoprefixer,让不 ...

  2. Coding源码学习第二部分(FunctionIntroManager.m)

    接上篇.上篇有一个细节忘了写,在Coding_iOS-Info.plist 里面添加了一个key 是 Status bar is initially hidden  Value 是 YES,在appl ...

  3. iOS 中Window优先级的问题

    在项目中,视频播放时候遇到网络切换需要弹出AlertView提醒用户,忽然发现转屏的时候播放View加到KeyWindow的时候把AleryView挡住了.如图 因为转屏的时候视图是直接加载到 [UI ...

  4. iOS 关于UIWindow 的认识

    UIWindow是一种特殊的UIView,通常在一个app中只会有一个UIWindow iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view ...

  5. 从壹开始前后端分离 [.netCore 填坑 ] 三十四║Swagger:API多版本控制,带来的思考

    前言 大家周二好呀,.net core + Vue 这一系列基本就到这里差不多了,今天我又把整个系列的文章下边的全部评论看了一下(我是不是很负责哈哈),提到的问题基本都解决了,还有一些问题,已经在QQ ...

  6. 【软工作业&思考】关于软工的一些概念性理解暨第一次阅读作业

    概述 项目 内容 本次作业所属课程 2019BUAA软件工程 周二班 本次作业要求 第1次个人作业当然,比这个更重要百倍的还是实实在在的思考,这也是标题如此命名的原因 我在本课程的目标 在原有实践经验 ...

  7. UIWindow 详解及使用场景

    首先来看一下UIWindow 继承关系 方法和属性 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIWindow : UIView //window的屏幕,默认是 [ ...

  8. Unityclient框架笔记二(组件实体开发模式的思考)

    Unity的Entity-Component-System实现的很美丽,很灵活.许多文章也对这样的组件实体的开发模式倍加推崇.由于它契合这么一条规则:优先使用组合而不是继承. 可是实际开发过程中,限制 ...

  9. 响应式设计的思考:媒体查询(media query)

    Jason Grigsby发表了篇文章,<CSS Media Query for Mobile is Fool’s Gold>对媒体查询(media query)吐槽,大意是在移动设备上使 ...

随机推荐

  1. jQuery -&gt; filter使用方法

    利用filter函数能够从wrapper set中过滤符合条件的DOM元素. 假设我们有一个内容例如以下的html文件,要获取类为external的<a>元素,使用filter能够非常ea ...

  2. html端编码规范

    理想的方式是让HTML只用于定义内容呈现的结构,让CSS控制内容呈现的样式,而所有功能的实现定义在JavaScript中

  3. CloudStack 4.0.2 vRouter导致重启后状态不正常

    最近总玩CloudStack + KVM,发现在重启CloudStack服务后,host(kvm)的状态老是为alert.日志里出现如下错误提示: ERROR [agent.manager.Agent ...

  4. TYVJ 2002 扑克牌 题解

    P2002 扑克牌 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 Admin生日那天,Rainbow来找Admin玩扑克牌……玩着玩着Rainbow觉得太没 ...

  5. SPSS Clementine 数据挖掘入门2

    下面使用Adventure Works数据库中的Target Mail作例子,通过建立分类树和神经网络模型,决策树用来预测哪些人会响应促销,神经网络用来预测年收入. Target Mail数据在SQL ...

  6. GPGPU OpenCL Reduction操作与group同步

    Reduction操作:规约操作就是由多个数生成一个数,如求最大值.最小值.向量点积.求和等操作,都属于这一类操作. 有大量数据的情况下,使用GPU进行任务并行与数据并行,可以收到可好的效果. gro ...

  7. csm pssm +pcf pcss sdsm

    这几个shadow算法 pcf是sample时候用的 按照一个mode采样几个位置 根据采样结果 决定0-1  可以是0.234 这样就不是 0或者1 就是soft了 主要讲下pcss 是啥 因为我之 ...

  8. 如何在Windows Server 2012 R2上安装SharePoint 2013

    笔者原以为是个挺容易个事儿, 毕竟是微软自家的产品安装在自家的操作系统上, 没想到还是让我费了半天劲.   写在这里吧, 方便其他的朋友.   具体步骤 ======================= ...

  9. 努力让java学习系统化

    这段日子接手一社区系统的开发.开发过程中感觉到自己接触到的和所作的多是业务逻辑性开发,对java开发到如今还没有一个清晰明白的路线,我越来越感觉到问题的重要性. 问题一:代码仅仅注重了功能实现,对代码 ...

  10. Unity5.1 新的网络引擎UNET(十五) Networking 引用--下

     孙广东 2015.7.21 本节提供了与网络系统一起使用的组件的具体信息. 10.Network Proximity Checker Suggest a change Success! Than ...