UIWindow中文詳解

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:中添加如下代碼:

  1. self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];  

    上面代碼中的self.window,是在application delegate中已經聲明過得屬性,用來保存window對象。如果你創建的是用於外部顯示的window,應該給它重新命名,並且需要設置bounds。

    創建window的時候,要吧bounds設置爲屏幕大小,不能有任何縮減。


    3.3把內容添加到window上

    每個window都有一個單獨的根視圖,這個根視圖包含了所有需要顯示的內容。它簡化了界面的變化操作。要顯示新的內容,只需要替換原來的根視圖。在window上添加視圖的話使用addSubview:方法即可,例如:

  1. [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外顯得屏幕模式配置

    略


原文鏈接:點擊打開鏈接 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章