服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - 深入了解iOS开发中UIWindow的相关使用

深入了解iOS开发中UIWindow的相关使用

2020-12-25 15:41一片枫叶 IOS

这篇文章主要介绍了深入了解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的显示就一切正常。”

延伸 · 阅读

精彩推荐
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17