自定義創(chuàng)建Window
UIWindow是UIView的子類,UIView對(duì)象是通過方法addSubview:顯示到父視圖吕世,但是window卻不需要這樣就能顯示,只需要設(shè)置hidden為NO即可,實(shí)際中一個(gè)window對(duì)象真正顯示到屏幕上還受到windowLevel影響
self.window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 400, 150, 150)];
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.view.backgroundColor = [UIColor redColor];
self.window1.rootViewController = vc1;
self.window1.windowLevel = 9;
[self.window1 makeKeyAndVisible];
- 注意: [window makeKeyWindow];
window.hidden = NO;
等價(jià)與
[self.window2 makeKeyAndVisible];
一個(gè)屏幕可以顯示幾個(gè)window斋荞?
理論上個(gè)數(shù)不限制,按需顯示虐秦。屏幕頂部的狀態(tài)欄平酿、alert彈窗、鍵盤都是常見的window悦陋。
與window相關(guān)的幾個(gè)知識(shí)點(diǎn)
1. windowLevel屬性
默認(rèn)值0.0染服,即系統(tǒng)定義的UIWindowLevelNormal。系統(tǒng)總共定義三種level叨恨,即如下
UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal = 0.f;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert = 2000.f;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar API_UNAVAILABLE(tvos) = 1000.f;
level越高在屏幕上顯示層級(jí)越靠前,如果多個(gè)window設(shè)置相同的level,這時(shí)顯示的層級(jí)就和設(shè)置hidden=NO的順序有關(guān)柳刮,最后設(shè)置的會(huì)顯示在最上層。
2. keyWindow
實(shí)際開發(fā)中我們常常會(huì)把一些顯示級(jí)別高或者全局顯示的視圖放到keyWindow痒钝,通過[UIApplication sharedApplication].keyWindow獲取使用秉颗。那keyWindow是什么,和其他window有什么不同送矩?keyWindow即主窗口蚕甥,參考官方文檔說明,在程序運(yùn)行期間只會(huì)存在一個(gè)主窗口栋荸,而且主窗口可以接收鍵盤事件及非觸摸事件菇怀。接收鍵盤事件好理解凭舶,什么是非觸摸事件呢?原文有相關(guān)描述
Whereas touch events are delivered to the window in which the touch occurred, events that don’t have an associated coordinate value are delivered to the key window.
英文能力有限爱沟,姑且理解為觸摸事件傳遞到當(dāng)前觸摸的window帅霜,同時(shí)會(huì)把這個(gè)觸摸事件傳遞到主窗口,但這個(gè)觸摸事件傳遞時(shí)不會(huì)帶著與坐標(biāo)系相關(guān)的值呼伸。這里非觸摸即沒有touch主窗口身冀,但依然可以接收到觸摸事件。
事實(shí)上任何window都可以設(shè)置為keyWindow括享,如果只是使用自定window展示alert信息或者toast信息搂根,沒有必要設(shè)置;如果alert里需要輸入信息铃辖,那就必須設(shè)置剩愧。
設(shè)置keyWindow的方法有兩個(gè),即
- (void)makeKeyWindow;
- (void)makeKeyAndVisible;
UIApplication.sharedApplication.delegate.window和UIApplication.sharedApplication.keyWindow有什么區(qū)別娇斩?
- [UIApplication sharedApplication].keyWindow
是設(shè)備上當(dāng)前正在顯示的窗口隙咸。這通常是您應(yīng)用程序的窗口,但也可能是系統(tǒng)窗口 - [UIApplication sharedApplication].delegate.window
是AppDelegate中定義的屬性窗口,是主window;
@property (strong, nonatomic) UIWindow *window; - [UIApplication sharedApplication].windows.firstObject
等價(jià)于
[UIApplication sharedApplication].delegate.window - [UIApplication sharedApplication].windows.lastObject
- [[UIApplication sharedApplication]windows].lastObject
用來獲取當(dāng)前屏幕上最上層的一個(gè)UIWindow成洗,但有可能不是當(dāng)前的window
- (void)alertView {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"測(cè)試" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"確認(rèn)", nil];
[alertView show];
// UIWindow *window = [UIApplication sharedApplication].keyWindow; //是上面alert的window
UIWindow *window = [UIApplication sharedApplication].delegate.window;// 是AppDelegate中定義的屬性窗口
UILabel *tempLabel =[[UILabel alloc]initWithFrame:CGRectMake(150, 150, 100, 20)];
tempLabel.font = [UIFont systemFontOfSize:16];
tempLabel.backgroundColor = [UIColor purpleColor];
tempLabel.text = @"測(cè)試window";
[window addSubview:tempLabel];
}
- 注意:UIWindow *window = [UIApplication sharedApplication].keyWindow,如果使用這個(gè)的時(shí)候,下面的tempLabel就會(huì)添加到UIAlertView所在的_UIAlertControllerShimPresenterWindow層,當(dāng)alert消失的時(shí)候,對(duì)應(yīng)的windows和tempLabel都會(huì)釋放
總結(jié):
https://developer.apple.com/documentation/uikit/uiwindow?language=objc
官方參考文檔 - 《Multiple Display Programming Guide for iOS》Understanding Windows and Screens