国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

深入了解iOS開發中UIWindow的相關使用

2019-10-21 18:57:11
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了深入了解iOS開發中UIWindow的相關使用,以及iOS8以后產生的相關變化,需要的朋友可以參考下
 

UIWindow是一種特殊的UIView,通常在一個app中只會有一個UIWindow。

iOS程序啟動完畢后,創建的第一個視圖控件就是UIWindow,接著創建控制器的view,最后將控制器的view添加到UIWindow上,于是控制器的view就顯示在屏幕上了。

一個iOS程序之所以能顯示到屏幕上,完全是因為它有UIWindow。也就說,沒有UIWindow,就看不見任何UI界面。

如何獲取UIWindow

(1)[UIApplication sharedApplication].windows  在本應用中打開的UIWindow列表,這樣就可以接觸應用中的任何一個UIView對象(平時輸入文字彈出的鍵盤,就處在一個新的UIWindow中);

(2)[UIApplication sharedApplication].keyWindow(獲取應用程序的主窗口)用來接收鍵盤以及非觸摸類的消息事件的UIWindow,而且程序中每個時刻只能有一個UIWindow是keyWindow;

注:經過代碼驗證,非keyWindow 也是可以接受鍵盤消息的;

提示:如果某個UIWindow內部的文本框不能輸入文字,可能是因為這個UIWindow不是keyWindow;

(3)view.window獲得某個UIView所在的UIWindow。

 

UIWindowLevel

我們知道UIWindow 有三個層級,分別是Normal ,StatusBar,Alert.輸出他們三個層級的值,我們發現從左到右依次是0,1000,2000,也就是說Normal級別是最低的,StatusBar處于中級,Alert級別最高。而通常我們的程序的界面都是處于Normal這個級別的,系統頂部的狀態欄應該是處于StatusBar級別,UIActionSheet和UIAlertView這些通常都是用來中斷正常流程,提醒用戶等操作,因此位于Alert級別。

根據window顯示級別優先原則,級別高的會顯示在最上層,級別低的在下面,我們程序正常顯示的view在最底層;

keyWindow

官方文檔中是這樣解釋的 “The key window is the one that is designated to receive keyboard and other non-touch related events. Only one window at a time may be the key window." 翻譯過來就是說,keyWindow是指定的用來接收鍵盤以及非觸摸類的消息,而且程序中每一個時刻只能有一個window是keyWindow。

 

觀察UIWindow的文檔,我們可以發現里面有四個關于window變化的通知:

  UIWindowDidBecomeVisibleNotification

  UIWindowDidBecomeHiddenNotification

  UIWindowDidBecomeKeyNotification

  UIWindowDidResignKeyNotification

  這四個通知對象中的object都代表當前已顯示(隱藏),已變成keyWindow(非keyWindow)的window對象,其中的userInfo則是空的。于是我們可以注冊這個四個消息,再打印信息來觀察keyWindow的變化以及window的顯示,隱藏的變動

變成keywindow 的流程是這樣的

1.程序默認的window先顯示出來

2.默認的window再變成keywindow

3.AlertView 的window顯示出來

4.默認的window變成keywindow

5.最終AlertView的window變成keywindow

 

iOS8開始UIWindow的bounds發生變化(Window本身發生了旋轉)
 
  iOS 7之前Window的bounds不會隨著方向而變化,但是到了iOS 8以后,隨著設備方向的旋轉,window.bounds.size.width和window.bounds.size.height也會相應發生變化。
 
  做個很簡單的測試,代碼如下:
 

 

復制代碼代碼如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];
    
    return YES;
}

 

- (void)orientationChanged:(NSNotification*)noti {
    
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    NSString *orientationDes = nil;
    switch (orientation) {
        case UIDeviceOrientationLandscapeLeft:
            orientationDes = @"UIInterfaceOrientationLandscapeRight";
            break;
        case UIDeviceOrientationLandscapeRight:
            orientationDes = @"UIInterfaceOrientationLandscapeLeft";
            break;
        case UIDeviceOrientationPortrait:
            orientationDes = @"UIInterfaceOrientationPortrait";
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            orientationDes = @"UIInterfaceOrientationPortraitUpsideDown";
            break;
        default:
            orientationDes = @"";
            break;
    }
    
    NSLog(@"system ver: %@, /rorientaion: %@, /rwindow bounds: %@",
          [UIDevice currentDevice].systemVersion,
          orientationDes,
          NSStringFromCGRect(self.window.bounds));
}

 


  示例代碼很簡單,新建一個工程,然后在delegate中直接添加以上代碼即可。
 
  iOS 8上運行結果為:

 

復制代碼代碼如下:

2014-06-04 09:26:32.016 SviOS8[4143:61114] system ver: 8.0,

 

orientaion: UIInterfaceOrientationLandscapeRight,

window bounds: {{0, 0}, {320, 480}}

2014-06-04 09:26:34.788 SviOS8[4143:61114] system ver: 8.0,

orientaion: UIInterfaceOrientationPortrait,

window bounds: {{0, 0}, {480, 320}}

2014-06-04 09:26:35.791 SviOS8[4143:61114] system ver: 8.0,

orientaion: UIInterfaceOrientationLandscapeLeft,

window bounds: {{0, 0}, {320, 480}}

2014-06-04 09:26:47.468 SviOS8[4143:61114] system ver: 8.0,

orientaion: UIInterfaceOrientationPortraitUpsideDown,

window bounds: {{0, 0}, {480, 320}}

 


  iOS 7及之前的版本運行結果為:
 

 

復制代碼代碼如下:
2014-06-04 09:39:00.527 SviOS8[4380:70b] system ver: 7.0.3,

 

orientaion: UIInterfaceOrientationLandscapeRight,

window bounds: {{0, 0}, {320, 480}}

2014-06-04 09:39:00.895 SviOS8[4380:70b] system ver: 7.0.3,

orientaion: UIInterfaceOrientationPortrait,

window bounds: {{0, 0}, {320, 480}}

2014-06-04 09:39:01.225 SviOS8[4380:70b] system ver: 7.0.3,

orientaion: UIInterfaceOrientationLandscapeLeft,

window bounds: {{0, 0}, {320, 480}}

2014-06-04 09:39:11.004 SviOS8[4380:70b] system ver: 7.0.3,

orientaion: UIInterfaceOrientationPortraitUpsideDown,

window bounds: {{0, 0}, {320, 480}}

 


  通過對比我們可以清晰的看到iOS 8中UIWindow在處理旋轉時策略的變更,雖然會因為與之前的版本不同導致現有項目布局存在的bug,但是可以看到iOS 8中的處理方式更加符合我們的預期,在豎向的時候我們就獲取到width < height, 在橫向則是 width > height,這個符合所見即所得的原則。
 
  題外話,不管是iOS 7還是之前的版本,以及最新出的iOS 8,所有的ViewController的bounds都是正確的,所以只需要堅持一個原則“所有布局都是基于VC.view.bounds布局,那么你的App的顯示就一切正常。”



注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 本溪市| 剑河县| 隆子县| 益阳市| 成都市| 双柏县| 任丘市| 浦江县| 绩溪县| 东山县| 维西| 中江县| 闸北区| 承德市| 闻喜县| 收藏| 肥西县| 清水县| 营口市| 抚州市| 沙洋县| 道孚县| 蒙阴县| 若尔盖县| 金沙县| 石嘴山市| 东源县| 利辛县| 锡林郭勒盟| 宁强县| 遂平县| 应用必备| 五大连池市| 通辽市| 广南县| 霍州市| 通化县| 江山市| 栾川县| 抚顺县| 台山市|