一、UIWindow是一種特殊的UIView,通常在一個(gè)app中只會(huì)有一個(gè)UIWindow。
iOS程序啟動(dòng)完畢后,創(chuàng)建的第一個(gè)視圖控件就是UIWindow,接著創(chuàng)建控制器的view,最后將控制器的view添加到UIWindow上,于是控制器的view就顯示在屏幕上了。
一個(gè)iOS程序之所以能顯示到屏幕上,完全是因?yàn)樗蠻IWindow。也就說,沒有UIWindow,就看不見任何UI界面。
二、通常我們可以采取兩種方法將view添加到UIWindow中:
1、addSubview
直接將view通過addSubview方式添加到window中,程序負(fù)責(zé)維護(hù)view的生命周期以及刷新,但是并不會(huì)為去理會(huì)view對(duì)應(yīng)的ViewController,因此采用這種方法將view添加到window以后,我們還要保持view對(duì)應(yīng)的ViewController的有效性,不能過早釋放。
2、rootViewController
rootViewController時(shí)UIWindow的一個(gè)遍歷方法,通過設(shè)置該屬性為要添加view對(duì)應(yīng)的ViewController,UIWindow將會(huì)自動(dòng)將其view添加到當(dāng)前window中,同時(shí)負(fù)責(zé)ViewController和view的生命周期的維護(hù),防止其過早釋放
三、 Window的作用。
在iOS中,一個(gè)window(也就是一個(gè)UIWindow對(duì)象)主要有這樣幾個(gè)作用:
1、展示app的可視內(nèi)容;
2、將事件分發(fā)給視圖以及其他對(duì)象;
3、和app的view controller一起處理屏幕旋轉(zhuǎn)。
其實(shí)在大多數(shù)情況下,第三方程序員不用做任何事情,UIWindow就能完成這些工作。所以很多時(shí)候,只有當(dāng)這個(gè)app需要支持另一個(gè)外設(shè)的屏幕的時(shí)候,程序員才會(huì)對(duì)UIWindow進(jìn)行操作。
四、 創(chuàng)建和配置一個(gè)Window。
- (void)configureExternalDisplayAndShowWithContent:(UIViewController*)rootVC
{
? ? ? ? self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
? ? ? ? self.window.windowLevel = UIWindowLevelNormal;
? ? ? ? self.window.screen = [UIScreen mainScreen];
? ? ? ? self.window.backgroundColor = [UIColor whiteColor];
? ? ? ? self.window.rootViewController = rootVC;
? ? ? ? // 我這里設(shè)置的 windowLevel 級(jí)別為 UIWindowLevelNormal,在與程序主窗口級(jí)別相等情況下,我想顯示額外的窗口,只需要把它的隱藏屬性改為 No,并不需要讓它成為主窗口。
? ? ? ? self.window.hidden = NO;
? ? ? ? //[self.window makeKeyAndVisible]; 顯示窗口,并成為關(guān)鍵窗口。
}
也可以通過 [UIApplication sharedApplication].keyWindow;獲取應(yīng)用程序的主window。
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[window addSubview:view];
五、 隱藏一個(gè)Window。
- (void)hideTheWindow
{
? ? ? ? self.window.hidden = YES;
? ? ? ? self.window = nil;
}
六、 常用屬性。
1、@property(nonatomic, strong) UIViewController *rootViewController // 設(shè)置window的根視圖控制器
2、@property(nonatomic) UIWindowLevel windowLevel
// UIWindow在顯示的時(shí)候會(huì)根據(jù)UIWindowLevel進(jìn)行排序的,即Level高的將排在所有Level比他低的層級(jí)的前面。
// 例如系統(tǒng)的 UIAlertView,它也是將試圖加載到window上面,它的Level為 UIWindowLevelAlert,所以它總是顯示在試圖層次最上層。
// 下面我們來(lái)看UIWindowLevel的定義:
const UIWindowLevel UIWindowLevelNormal; // level:?0.000000
const UIWindowLevel UIWindowLevelAlert; // level:?2000.000000
const UIWindowLevel UIWindowLevelStatusBar; // level:?1000.000000
typedef CGFloat UIWindowLevel;
// 這個(gè)屬性默認(rèn)值為 UIWindowLevelNormal;
3、 @property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow
// 一個(gè)布爾值,該值指示是否窗口是應(yīng)用程序的關(guān)鍵窗口。一個(gè)應(yīng)用程序只能有一個(gè)keyWindow。
七、 常用方法。
1、 - (void)makeKeyAndVisible。 // 顯示窗口,并使其成為關(guān)鍵窗口。
2、 - (void)makeKeyWindow。 // 設(shè)置窗口為關(guān)鍵窗口。
八、 坐標(biāo)轉(zhuǎn)換。
1、 - (CGPoint)convertPoint:(CGPoint)point toWindow:(UIWindow *)window。
// 將當(dāng)前window的坐標(biāo)系統(tǒng)轉(zhuǎn)換為另一個(gè)window的坐標(biāo)系統(tǒng)的點(diǎn)。
2、 - (CGPoint)convertPoint:(CGPoint)point fromWindow:(UIWindow *)window。
// 將一個(gè)點(diǎn)從一個(gè)給定window的坐標(biāo)系統(tǒng)轉(zhuǎn)換為當(dāng)前window的坐標(biāo)系統(tǒng)。
3、 - (CGRect)convertRect:(CGRect)rect toWindow:(UIWindow *)window。
// 將矩形從當(dāng)前window的坐標(biāo)轉(zhuǎn)換為另一個(gè)window的坐標(biāo)系統(tǒng)。
4、 - (CGRect)convertRect:(CGRect)rect fromWindow:(UIWindow *)window。
// 將矩形從另一個(gè)window的坐標(biāo)系轉(zhuǎn)換為當(dāng)前window的坐標(biāo)系。
八、 軟鍵盤相關(guān)通知。
1、 NSString *const UIKeyboardWillShowNotification;
// 在軟鍵盤顯示前發(fā)送通知。
2、 NSString *const UIKeyboardDidShowNotification;
// 在軟鍵盤顯示后發(fā)送通知。
3、 NSString *const UIKeyboardWillHideNotification;
// 在軟鍵盤消失前發(fā)送通知。
4、 NSString *const UIKeyboardDidHideNotification;
// 在軟鍵盤消失后發(fā)送通知。
九、 UIWindow相關(guān)通知。
1、 NSString *const UIWindowDidBecomeVisibleNotification;
// 當(dāng)window顯示的時(shí)候發(fā)送通知。
2、 NSString *const UIWindowDidBecomeHiddenNotification;
// 當(dāng)window隱藏后發(fā)送通知。
3、 NSString *const UIWindowDidBecomeKeyNotification;
// 當(dāng)window成為關(guān)鍵window的時(shí)候發(fā)送通知。
4、 NSString *const UIWindowDidResignKeyNotification;
// 當(dāng)window不是關(guān)鍵window的時(shí)候發(fā)送通知。
當(dāng)你使用一個(gè)額外的window,并使其成為關(guān)鍵window的時(shí)候,它的流程如下:
1、? 顯示額外的window。
2、 把應(yīng)用原有的window設(shè)置為不是關(guān)鍵window(因?yàn)橐粋€(gè)應(yīng)用程序只能有一個(gè)關(guān)鍵window)。
3、 把額外的window設(shè)置為關(guān)鍵window。
當(dāng)你移除一個(gè)額外的關(guān)鍵window的時(shí)候,它的流程如下:
1、 把額外的關(guān)鍵window設(shè)置為不是關(guān)鍵window(因?yàn)橐粋€(gè)應(yīng)用程序只能有一個(gè)關(guān)鍵window)。
2、 把應(yīng)用原有的window設(shè)置為關(guān)鍵window。
3、 隱藏額外的window。