iOS應(yīng)用開發(fā)中視圖控件UIWindow的基本使用教程
一、簡單介紹
iPhone應(yīng)用程序通常只有一個窗口,表示為一個UIWindow類的實例。應(yīng)用程序在啟動時(或者從nib文件進(jìn)行裝載)創(chuàng)建這個窗口,并往窗口中加入一或多個視圖并顯示出來。之后我們很少需要再次引用它。UIWindow對象是所有UIView的根,管理和協(xié)調(diào)的應(yīng)用程序的顯示。一般應(yīng)用程序只有一個UIWindow對象,即使有多個UIWindow對象,也只有一個UIWindow可以接受到用戶的觸屏事件。
在IOS中,UIWindow對象并沒有像windows應(yīng)用程序中常見的關(guān)閉框或標(biāo)題欄這樣的部件,普通用戶不能直接對其進(jìn)行關(guān)閉或其它操作。所有對窗口的操作都需要通過其編程接口來實現(xiàn)。應(yīng)用程序可以借助窗口對象來進(jìn)行事件傳遞。窗口對象會持續(xù)跟蹤當(dāng)前的第一響應(yīng)者對象,并在UIApplication對象提出請求時將事件傳遞它。
UIWindow是一種特殊的UIView,通常在一個app中只會有一個UIWindow
在Mac OS X中,NSWindow的父類是NSResponder;而在iPhone OS中,UIWindow的父類是UIView。因此,UIWindow窗口在IOS中也是一個視圖對象。
在創(chuàng)建應(yīng)用程序窗口時,應(yīng)該總是將其初始的邊框尺寸設(shè)置為整個屏幕的大小。如果您的窗口是從nib文件裝載得到,Interface Builder并不允許創(chuàng)建比屏幕尺寸小的窗口;然而,如果您的窗口是通過編程方式創(chuàng)建的,則必須在創(chuàng)建時傳入期望的邊框矩形。除了屏幕矩形之外,沒有理由傳入其它邊框矩形。
iOS程序啟動完畢后,創(chuàng)建的第一個視圖控件就是UIWindow,接著創(chuàng)建控制器的view,最后將控制器的view添加到UIWindow上,于是控制器的view就顯示在屏幕上了
一個iOS程序之所以能顯示到屏幕上,完全是因為它有UIWindow。也就說,沒有UIWindow,就看不見任何UI界面
補(bǔ)充:UIWindow是創(chuàng)建的第一個視圖控件(創(chuàng)建的第一個對象是UIapplication)如下圖:
添加
先創(chuàng)建UIwindow,再創(chuàng)建控制器,創(chuàng)建控制器的view,然后將控制器的view添加到UIWindow上。
文檔中關(guān)于該部分的解釋:
二、UIWindow的創(chuàng)建過程
1.簡單說明
創(chuàng)建一個空的項目,就可以看到UIWindow是怎么出來的了。在程序啟動完畢之后就會調(diào)用一次,創(chuàng)建過程如下:
提示:應(yīng)用程序啟動之后,先創(chuàng)建Application,再創(chuàng)建它的代理,之后創(chuàng)建UIwindow。UIWindow繼承自UIview。
2.把view添加到uiwindow
創(chuàng)建一個控制器,把view添加到uiwindow上面(有兩種方式)
(1)直接將控制器的view添加到UIWindow中,并不理會它對應(yīng)的控制器
[self.window addsubview:vc.view];
(2)設(shè)置uiwindow的根控制器,自動將rootviewcontroller的view添加到window中,負(fù)責(zé)管理rootviewcontroller的生命周期
[self.window.rootviewcontroller=vc];
兩個方法的區(qū)別:
以后的開發(fā)中,建議使用(2).因為方法(1)存在一些問題,比如說控制器上面可能由按鈕,需要監(jiān)聽按鈕的點(diǎn)擊事件,如果是1,那么按鈕的事件應(yīng)該由控制器來進(jìn)行管理。但控制器是一個局部變量,控制器此時已經(jīng)不存在了,但是控制器的view還在,此時有可能會報錯。注意:方法執(zhí)行完,這個控制器就已經(jīng)不存在了。
問題描述1:當(dāng)view發(fā)生一些事件的時候,通知控制器,但是控制器已經(jīng)銷毀了,所以可能出現(xiàn)未知的錯誤。
問題描述2:添加一個開關(guān)按鈕,讓屏幕360度旋轉(zhuǎn)(兩者的效果不一樣)。當(dāng)發(fā)生屏幕旋轉(zhuǎn)事件的時候,UIapplication對象會將旋轉(zhuǎn)事件傳遞給uiwindow,uiwindow又會將旋轉(zhuǎn)事件傳遞給它的根控制器,由根控制器決定是否需要旋轉(zhuǎn)
UIapplication->uiwindow->根控制器(第一種方式?jīng)]有根控制器,所以不能跟著旋轉(zhuǎn))。
提示:不通過控制器的view也可以做開發(fā),但是在實際開發(fā)中,不要這么做,不要直接把view添加到UIWindow上面去。因為,難以管理。
3.在有storyboard的項目中,UIWindow是如何創(chuàng)建的?
為什么創(chuàng)建一個storyboard,沒有看到創(chuàng)建uiwindow的過程?
它其實是把創(chuàng)建UIWindow的過程給屏蔽起來了。可以把代理的UIWindow的屬性的值打印出來NSLog(@“window=%p”,self.window);打印出來確實是有值的,說明確實創(chuàng)建了UIWindow.不僅創(chuàng)建了UIWindow,默認(rèn)還創(chuàng)建了UIWindow對應(yīng)的控制器,也可以打印進(jìn)行查看。NSLog(@“%@“,self.window.rootviewcontroller);
有storyboard的項目中的創(chuàng)建過程:
當(dāng)用戶點(diǎn)擊應(yīng)用程序圖標(biāo)的時候,先執(zhí)行Main函數(shù),執(zhí)行UIApplicationMain(),根據(jù)其第三個和第四個參數(shù)創(chuàng)建Application,創(chuàng)建代理,并且把代理設(shè)置給application(看項目配置文件info.plist里面的storyboard的name,根據(jù)這個name找到對應(yīng)的storyboard),開啟一個事件循環(huán),當(dāng)程序加載完畢,他會調(diào)用代理的didFinishLaunchingWithOptions:方法。在調(diào)用didFinishLaunchingWithOptions:方法之前,會加載storyboard,在加載的時候創(chuàng)建一個window,接下來會創(chuàng)建箭頭所指向的控制器,把該控制器設(shè)置為UIWindow的根控制器,接下來再將window顯示出來,即看到了運(yùn)行后顯示的界面。(提示:關(guān)于這部分可以查看story的初始化的文檔)
三、如何獲取window?
1.主窗口和次窗口
[self.window makekeyandvisible]讓窗口成為主窗口,并且顯示出來。有這個方法,才能把信息顯示到屏幕上。
因為Window有makekeyandvisible這個方法,可以讓這個Window憑空的顯示出來,而其他的view沒有這個方法,所以它只能依賴于Window,Window顯示出來后,view才依附在Window上顯示出來。
[self.window make keywindow]//讓uiwindow成為主窗口,但不顯示。
2.獲取UIwindow
(1)[UIApplication sharedApplication].windows 在本應(yīng)用中打開的UIWindow列表,這樣就可以接觸應(yīng)用中的任何一個UIView對象(平時輸入文字彈出的鍵盤,就處在一個新的UIWindow中)
(2)[UIApplication sharedApplication].keyWindow(獲取應(yīng)用程序的主窗口)用來接收鍵盤以及非觸摸類的消息事件的UIWindow,而且程序中每個時刻只能有一個UIWindow是keyWindow。
提示:如果某個UIWindow內(nèi)部的文本框不能輸入文字,可能是因為這個UIWindow不是keyWindow
(3)view.window獲得某個UIView所在的UIWindow
四、四大對象的關(guān)系圖
五、主窗口和次窗口說明
代碼:
// 程序啟動完畢之后就會調(diào)用一次
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 1.創(chuàng)建UIWindow
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// 設(shè)置UIWindow的背景顏色
self.window.backgroundColor = [UIColor redColor];
// 讓UIWindow顯示出來(讓窗口成為主窗口 并且顯示出來)
// 一個應(yīng)用程序只能有一個主窗口
[self.window makeKeyAndVisible];
// 讓UIWindow成為主窗口
// [self.window makeKeyWindow];
// 2. 再創(chuàng)建一個窗口
UIWindow *w2 = [[UIWindow alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
w2.backgroundColor = [UIColor yellowColor];
[w2 makeKeyAndVisible];
self.w2 = w2;
// 3.創(chuàng)建兩個文本輸入框
// 3.1將文本輸入框添加到window中
UITextField *tx1 = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 200, 40)];
tx1.borderStyle = UITextBorderStyleRoundedRect;
[self.window addSubview:tx1];
// 3.2將文本輸入框添加到w2中
UITextField *tx2 = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 100, 40)];
tx2.borderStyle = UITextBorderStyleRoundedRect;
[self.w2 addSubview:tx2];
// 獲取應(yīng)用程序的主窗口
NSLog(@"%@", [UIApplication sharedApplication].keyWindow);
return YES;
}
代碼說明:
再創(chuàng)建一個窗口(主窗口和次窗口的區(qū)別)
局部變量,需要定義一個Window屬性來保存變量。
window的屬性定義為strong,就是為了讓其不銷毀。
一個應(yīng)用程序只能有一個主窗口,程序中創(chuàng)建了兩個Window,那么誰是主窗口?后面的窗口能覆蓋前面的窗口。
提示:如果UItextfield不顯示,可以考慮設(shè)置它的樣式,因為其創(chuàng)建默認(rèn)是虛線的,沒有邊框。
在ios7里邊,主窗口和次窗口是沒有區(qū)別的
在ios7以前中有區(qū)別:哪個是主窗口,后面設(shè)置為主窗口會把之前設(shè)置的覆蓋掉。(只有主窗口才能響應(yīng)鍵盤的輸入事件,如果不能輸入內(nèi)容,可以查看是否是顯示在主窗口上,不在主窗口上的不能響應(yīng)。)
六、補(bǔ)充說明
在有storyboard中的創(chuàng)建過程:
先執(zhí)行Main函數(shù),執(zhí)行UIApplicationMain(),根據(jù)其第三個和第四個參數(shù)創(chuàng)建Application,創(chuàng)建代理,并且把代理設(shè)置給application,根據(jù)項目配置文件info.plist里面的storyboard的name,找到對應(yīng)的storyboard,接下來創(chuàng)建一個window,之后創(chuàng)建它的初始化控制器(就是箭頭所指向的控制器),自動把該控制器設(shè)置為UIWindow的根控制器,接下來再將window顯示出來,即看到了運(yùn)行后顯示的界面。
注意這個控制器屬性面板上的“初始化控制器屬性”。
在沒有storyboard中的創(chuàng)建過程:
先執(zhí)行Main函數(shù),執(zhí)行UIApplicationMain(),根據(jù)其第三個和第四個參數(shù)創(chuàng)建Application,創(chuàng)建代理,并且把代理設(shè)置給application,開啟一個事件循環(huán),當(dāng)程序加載完畢,他會調(diào)用代理的didFinishLaunchingWithOptions:方法。在該方法中,會創(chuàng)建一個Window,然后創(chuàng)建一個控制器,并把該控制器設(shè)置為UIWindow的根控制器,接下來再將window顯示出來,即看到了運(yùn)行后顯示的界面。
- iOS開發(fā)中UIDatePicker控件的使用方法簡介
- 學(xué)習(xí)iOS開關(guān)按鈕UISwitch控件
- 詳解iOS開發(fā)中UIPickerView控件的使用方法
- iOS App開發(fā)中的UIPageControl分頁控件使用小結(jié)
- iOS應(yīng)用開發(fā)中的文字選中操作控件UITextView用法講解
- iOS開發(fā)中UIImageView控件的常用操作整理
- 詳解iOS App開發(fā)中改變UIButton內(nèi)部控件的基本方法
- 詳解iOS開發(fā)中UItableview控件的數(shù)據(jù)刷新功能的實現(xiàn)
- iOS App中UIPickerView選擇欄控件的使用實例解析
- iOS中各種UI控件屬性設(shè)置示例代碼
相關(guān)文章
Unity3d發(fā)布IOS9應(yīng)用時出現(xiàn)中文亂碼的解決方法
這里給大家分享的是使用UNity3d發(fā)布IOS9應(yīng)用的時候,遇到出現(xiàn)中文亂碼的現(xiàn)象的解決方法,核心內(nèi)容非常簡單就是批量修改NGUI的label字體,下面把代碼奉上。2015-10-10iOS App開發(fā)中UISearchBar搜索欄組件的基本用法整理
iOS開發(fā)組件中自帶的UISearchBar提供了很多基礎(chǔ)和好用的搜索欄UI功能,下面就來總結(jié)一下iOS App開發(fā)中UISearchBar搜索欄組件的基本用法整理,需要的朋友可以參考下2016-05-05iOS實現(xiàn)去除html標(biāo)簽的方法匯總
相信大家在做網(wǎng)站的時候,經(jīng)常會遇到去除html標(biāo)簽的問題,下面這篇文章主要給大家總結(jié)介紹了關(guān)于iOS如何實現(xiàn)去除html標(biāo)簽的一些方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-10-10Objective-C實現(xiàn)無限循環(huán)輪播器
這篇文章主要介紹了Objective-C實現(xiàn)無限循環(huán)輪播器的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-05-05iOS優(yōu)化UITableViewCell高度計算的一些事兒
這iOS開發(fā)中對于UITableViewCell高度自適應(yīng)的文章已經(jīng)很多很多,但都不是自己所需要的,下面篇文章主要給大家介紹了關(guān)于iOS優(yōu)化UITableViewCell高度計算的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-11-11