1.window
每個iOS應用都會有至少一個window,這個window就是UIWindow的實例,也有些應用會有多個window。window會有如下幾個職責:
- 它包含了應用中的可見內容;
- 它在視圖和應用對象之間傳遞觸摸事件中起很重要的作用;
- 它和視圖控制器配合完成方向轉變。
在iOS系統中,windows沒有標題欄、關閉框以及其他可視控件。一個window就是一個或多個視圖的空白容器,而且應用不能通過window來改變自己的顯示內容。當你想要改變現顯示容的時候,改變最上層的視圖就可以了。
大多數iOS應用在其生命週期內只使用一個window,這個window從應用的主nib文件中加載,鋪滿整個主屏幕。當然,如果你的應用支持外部顯示,它會額外創建一個window,用於外部顯示。系統會創建其他典型的window,一般是在響應特殊事件時創建,例如來電顯示。
2.牽扯到window的任務
對於大多數應用而言,和window相關操作只是在window創建的時候。然而,你可以使用window對象去執行一些和應用相關的任務,例如:
- 利用window對象去設置窗口(window)的原點和座標系統。比如在使用一個特殊view之前你想改變window的座標系統(譯註:手動切換橫豎屏就得用到這個知識點)。
- 在window的通知方法中可以追蹤到window相關的變化。window會在顯示、隱藏或者同意了註冊key的狀態的時候發送相應的通知。你可以在其他地方監聽這些通知並作出相應操作。
3.window的創建和配置
你可以代碼或者InterfaceBuilder來創建並設置window。您在啓動時創建了窗口,並應保留它,並將其保存到應用程序代理對象中的引用。如果需要額外的window,則在需要用的時候創建即可。
創建window不需要考慮應用實在前臺啓動還是後臺啓動。創建和設置一個window不需要花太多資源。如果程序直接在後臺啓動,那麼你就不能讓window可見,直到window到前臺之後再讓其可見。
3.1用Interface Builder創建window
用IB創建window非常簡單,因爲Xcode的工程模板可以替你你創建。每個應用都會包含一個主XIB文件,這個XIB就包含了一個主window。另外,這些模板也爲window在應用的代理對象中定義了outlet,你可以在代碼中通過outlet取到window對象。
注意:在使用IB創建window的時候,應該在屬性設置欄中設置爲全屏。如果沒有設置爲全屏,且window小於手機的屏幕尺寸,那麼一些視圖的觸摸時間肯接收不到。這是因爲window接受不到自己區域以外的觸摸事件。如果視圖的觸摸點沒在window的區域範圍內,則響應不到觸摸事件。所以要確保window是全屏。
如果你重構代碼時用到 IB添加window,也很簡單,像XIB文件中拖一個window對象,然後進行如下操作:
- 要在運行時訪問window,應該把window和outlet相連。outlet一般情況下是在application delegate中,也可以是這個NIB文件對應的代碼文件。
- 重構過程中如果需要新建一個主NIB,那就得在info.plist文件中設置
NSMainNibFil
鍵。通過設置NSMainNibFil
的值來確保這個window在代理方法application:didFinishLaunchingWithOptions:
被調用是得到加載。
3.2純代碼創建window
如果你跟喜歡用代碼創建window,那麼你應該在代理方法application:didFinishLaunchingWithOptions:
中添加如下代碼:
- self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
上面代碼中的
self.window
,是在application delegate中已經聲明過得屬性,用來保存window對象。如果你創建的是用於外部顯示的window,應該給它重新命名,並且需要設置bounds。
創建window的時候,要吧bounds設置爲屏幕大小,不能有任何縮減。
3.3把內容添加到window上
每個window都有一個單獨的根視圖,這個根視圖包含了所有需要顯示的內容。它簡化了界面的變化操作。要顯示新的內容,只需要替換原來的根視圖。在window上添加視圖的話使用addSubview:
方法即可,例如:
- [window addSubview:viewController.view];
替代前面的代碼的是,你可以在nib文件中選擇性的設置rootViewController
屬性。這個屬性提供便利的方法讓你去設置window中的根視圖。如果這個屬性在window加載之後被設置了,UIKit會自動去吧viewController中的view設爲window的根視圖。這個rootViewController只是用來爲window設置根視圖的,而不是用來讓window和viewController交互的。
你可以根據你的意願把任何view作爲window的根視圖。根據你的界面設計,你可以把系統提供的view設爲根視圖,也可以把自定義view設爲根視圖。系統視圖可以是scroll views, table views, and image views等等。
設置根視圖的時候,應該確保視圖在window的尺寸範圍之內。一些應用沒有狀態欄或者狀態欄是透明的,這時你只需要讓根視圖充滿window就行。如果有狀態欄且不是透明的,那麼設置視圖尺寸的時候應該減去狀態欄的高度,以確保不被狀態欄遮擋。
注意:如果根視圖是由一些container型的控制器提供(例如tab bar controller, navigation controller, 或split-view controller),就不需要手動設置其尺寸。系統會自動爲你設好。
3.4改變window等級
每個UIWindow都有一個windowLevel
屬性,它決定了window之間的關係。多數情況下是不需要去設置這個屬性的,一個新的window在創建時就被自動設置normal window level,normal
window level表示這個window現實和當前應用相關的內容。Higher window level的window展示時會浮窗於應用界面,例如狀態欄和警告信息。儘管你可以手動設置level,其實當你用到特定界面的時候系統已經爲你設置好了。例如當你隱藏或顯示狀態欄的時候,系統自動創建所需要的window。
4.window發生變化時的操作
四個通知:
5.用外部顯示來顯示內容
5.1處理屏幕鏈接和非鏈接的通知
略
5.2外部顯示的window配置
略
5.3外顯得屏幕模式配置
略
原文鏈接:點擊打開鏈接