以前从来没注意过的UIWindow

好久没有更新博客了O.O因为最近工作好忙TAT
当然忙的时候也积累了很多以前没注意的问题。所以又有了很多能写成博客的素材O.O

所以这次先来研究一下我以前从来没注意过的UIWindow好了。


Window的作用



在iOS中,一个window(也就是一个UIWindow对象)主要有这样几个作用:

  1. 展示app的可视内容;
  2. 将事件分发给视图以及其他对象;
  3. 和app的view controller一起处理屏幕旋转。

其实在大多数情况下,第三方程序员不用做任何事情,window就能完成这些工作。所以很多时候,只有当这个app需要支持另一个外设的屏幕的时候,程序员才会对window进行操作。


创建window



有好几种创建window的方式:


使用storyboard:

如果程序员为app创建了一个storyboard,并在info.plist中指定它为main storyboard,那么在app启动的时候,iOS会自动帮程序员做这样几件事情:

  1. 实例化一个window;
  2. 加载main storyboard,并且实例化其中的root view controller;
  3. 将这个view controller赋值给window.rootViewController,并显示这个window。
使用nib文件:

如果不使用storyboard,也可以用nib文件来代替。将一个window对象拖拽到Interface Builder文件中,并将这个文件指定为app的main interface。那么在app启动的时候,iOS也会自动创建window对象。
为了确保window的大小与屏幕大小吻合,需要在Interface Builder中对window对象勾选Full Screen at Launch这个属性。

手写代码:

当然也可以通过手写代码的方式创建window。比如官方示例代码:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    myViewController = [[MyViewController alloc] init];
    window.rootViewController = myViewController;
    [window makeKeyAndVisible];
    
    return YES;
}

需要注意的是,window的尺寸永远应该是屏幕的尺寸,不应该考虑状态栏等元素,因为这些是view controller应该处理的问题。


Action Sheet和Alert View



知道了window的存在之后,感觉也能知道很多事情。

比如,iOS中的UIActionSheet和UIAlertView其实是显示在另一个window上的。

监听UIWindowDidResignKeyNotification,可以发现,当action sheet弹出时,UIWindowDidResignKeyNotification通知被发送了。此时检查app所在的window,发现它已经不再是key window了。


悬浮窗



以前我总以为所有的view都是被拘束在UIViewController的view中的,所以一直不知道悬浮窗的效果应该如何实现。但实际上,UIWindow本身就是一个UIView,可以直接在UIWindow上添加子视图,做出悬浮的效果。(虽然这样不符合苹果的设计规范)

[[[UIApplication sharedApplication].delegate window] addSubview:suspendView];

呈现出视图悬浮在app之上的效果:


悬浮窗效果

黑科技?



好奇尝试了一些奇怪的情景O.O

如果window没有占满整个屏幕会怎样呢?

默认情况下,window中的视图依然能照常显示,但是触屏事件无法正常分发。

官方文档中这样描述:

Because a window doesn’t receive touch events outside of its bounds and views aren’t clipped to the window’s bounds by default, an improperly sized window might not be able to deliver touch events to all its views.

用手写代码的方式可以创建一个任意大小的window,比如在application:willFinishLaunchingWithOptions:方法中写:

self.window = [[XSQWindow alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];

运行程序时,window中的子视图依然可以照常显示,包括window外的部分,但是在点击window之外的区域时,终端会输出错误信息:

unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <XSQWindow: 0x14c614a20; baseClass = UIWindow; frame = (0 0; 200 200); gestureRecognizers = <NSArray: 0x174059740>; layer = <UIWindowLayer: 0x174220e60>>

并且触屏点对应的视图无法接收到这次的触屏事件。

如果在一个app中创建多个window会怎么样?

也是可以做到在一个app中创建多个window的,而且似乎也不会怎么样。
触屏事件会根据触摸点的位置,被UIApplication分发到对应的window中。


参考

UIWindow Class Reference
Understanding Windows and Screens
iOS开发UI篇—控制器的创建
关于UIWindow的一点儿思考
Event Delivery: The Responder Chain

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,477评论 1 14
  • 7、不使用IB是,下面这样做有什么问题? 6、请说说Layer和View的关系,以及你是如何使用它们的。 1.首先...
    AlanGe阅读 662评论 0 1
  • 骑车20分钟,最近没有休息好,好困啊
    SPP164810阅读 118评论 0 0
  • http://pan.baidu.com/share/link?shareid=3562246143&uk=218...
    奔跑的马齿苋阅读 216评论 0 0
  • js总的来说 1.被所有主流的浏览器支持并被大部分网页使用 2.他可以在网页上呈现动态效果 对于js代码的位置 1...
    tinaaaabbb阅读 434评论 0 2