• iOS学习笔记(3)— 屏幕旋转


    一、屏幕旋转机制: 

      iOS通过加速计判断当前的设备方向和屏幕旋转。当加速计检测到方向变化的时候,屏幕旋转的流程如下:

      1、设备旋转时,系统接收到旋转事件。

      2、系统将旋转事件通过AppDelegate通知当前的主Window。

      3、window通知它的rootViewController。

        4、rootViewController判断所支持的旋转方向,完成旋转。

      iOS系统中屏幕旋转事件没有像触碰事件那样进行hitTest,所以只有rootViewController才能接收到屏幕旋转的事件,在其他viewController中实现旋转控制方法是不会被调用的。当屏幕旋转时应用程序会发出UIDeviceOrientationDidChangeNotification通知,这样任何关系方向变化的view都可以通过注册该通知,在设备方向发生变化的时候发生响应。

     

     

      在响应设备旋转时,我们可以通过UIViewController的方法实现更细粒度的控制,当view controller接收到window传来的方向变化的时候,流程如下:

     

      1、首先判断当前viewController是否支持旋转到目标方向,如果支持则继续,否则流程就此结束。

     

      2、调用 willRotateToInterfaceOrientation:duration: 方法,通知view controller将要旋转到目标方向。如果该viewController是一个container view controller的话,它会继续调用其content view controller的该方法。这个时候我们也可以暂时将一些view隐藏掉,等旋转结束以后在现实出来。

     

      3、window调整显示的view controller的bounds,由于view controller的bounds发生变化,将会触发 viewWillLayoutSubviews 方法。这个时候interfaceOrientationstatusBarOrientation方向还是原来的方向。

     

      4、接着当前view controller的 willAnimateRotationToInterfaceOrientation:duration: 方法将会被调用。系统将会把该方法中执行的所有属性变化放到animation block中。

     

      5、执行屏幕旋转动画。

     

      6、最后调用 didRotateFromInterfaceOrientation: 方法,通知view controller旋转动画执行完毕。这个时候我们可以将第二部隐藏的view再显示出来。

     

      整个响应过程如下图所示:

     

     

      

     

      以上就是UIKit下一个完整的屏幕旋转流程,我们只需要按照提示做出相应的处理就可以完美的支持屏幕旋转。

    二、旋转机制实现

     

     

      iOS5屏幕旋转控制

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
    {
        return YES;
    }

      返回YES就是允许旋转,NO就是不允许

      根据toInterfaceOrientation 可以控制屏幕允许旋转的方向,比如不支持Home按钮朝上这种屏幕方向。代码如下:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
    {
       if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
        {
            return NO;
        }
        return YES;
    }
    

      

      这种方法已经被苹果列为deprecated。但为了兼容iOS5及以前的版本还需要继续实现。

     

      iOS6屏幕旋转控制

      - (BOOL)shouldAutorotate  默认返回YES,当为YES时允许转屏,否则为不允许。

      - (NSUInteger)supportedInterfaceOrientations 决定可以转哪个方向。如果所有方向都支持返回 UIInterfaceOrientationMaskAll,如果不允许Home键朝上返回UIInterfaceOrientationMaskAllButUpsideDown。

     

    三、注意事项

      1、旋屏后的frame

      如果直接把window.rootviewController = (UIViewController*)vc;旋屏的时候vc的frame一直都是保持竖屏状态,bounds是正确的。
      如果使用UINavigationController的rootviewControoler 设置为vc,然后那NavigationControllerView去作为window的rootView,在旋屏的时候会发现vc的frame和bounds都是正确的。
      结论:判断屏幕尺寸用bounds比frame更准确。
     
      2、如果viewController或者view是隐藏状态的话就接收不到屏幕旋转事件,那么重新显示就会有问题。可以通过 viewWillAppear 函数解决这个问题。
      3、屏幕旋转的时候,让界面暂时不响应事件。
      4、对于view层级比较复杂的视图,使用截图替换当前的视图,旋转完成后再替换回原来的视图。
      5、旋转后调用tableview的reload方法,保证屏幕尺寸变化后cell可以充满全屏。
  • 相关阅读:
    rem 适配
    1px实现方案
    伪类选择器
    css中如何做到容器按比例缩放
    rem移动端适配方案
    Quartz.NET实现作业调度
    iPhone X
    优化hexo访问速度-将hexo部署到云主机VPS
    网页设计命名规范
    网站注册页面
  • 原文地址:https://www.cnblogs.com/zy1987/p/3195712.html
Copyright © 2020-2023  润新知