屏幕旋转示例.jpeg
前段时间抽空总结了一下iOS
视频播放的基本用法,发现这其中还有一个我们无法绕过的问题,那就是播放界面的旋转与适配。的确,视频播放与游戏类型的App
经常会遇到这个的问题。由于至今接手的项目中不常涉及这块知识疏于总结,在搜索了一些资料后也发现都很散乱,所以决定在这里重新整理一下。
- 两种屏幕旋转的触发方式
- 开启屏幕旋转的全局权限
- 开启屏幕旋转的局部权限(视图控制器)
- 实现需求:项目主要界面竖屏,部分界面横屏
一、最让人纠结的三种枚举
刚开始接触屏幕旋转这块知识的时候,最让人抓狂的也许就是三种相关的枚举类型了,它们就是:
正常情况下,我们的App
从Appdelegate
中启动,而Appdelegate
所持有唯一的Window
对象是全局的,所以在Appdelegate
文件中设置屏幕旋转也是全局有效的。
下面的代码设置了只支持竖屏和右旋转:
需要注意:如果我们实现了Appdelegate的这一方法,那么我们的App的全局旋转设置将以这里的为准,即使前两种方法的设置与这里的不同。
五、开启屏幕旋转的局部权限(视图控制器)
在设置了全局所支持的旋转方向后,接着就开始设置具体的控制器界面了。我们在上面已经说明了关于旋转的优先级了。而这里主要涉及了三种视图控制器:
自全局权限开启之后,接下来具有最高权限的就是Window
的根视图控制器rootViewController
了。如果我们要具体控制单个界面UIViewController
的旋转就必须先看一下根视图控制器的配置情况了;
比如说我们设置要单个视图控制器可以自动旋转,这需要在视图控制器中增加shouldAutorotate
方法返回YES
或者NO
来控制。但如果存在上层根视图控制器,而我们只在这个视图控制器中实现方法,会发现这个方法是不走的,因为这个方法被上层根视图控制器拦截了;
理解这个原理后,我们有两种方法实现自动可控的旋转设置:
方法1:逐级设置各视图控制器,高优先级的视图控制器影响低优先级控制器,
//返回导航控制器的顶层视图控制器的自动旋转属性,因为导航控制器是以栈的原因叠加VC的到这里,我们就应该明白了,其实就是高优先级的视图控制器要跟随低优先级控制器的旋转配置。这样就能够达到目的;
方法2: 另辟蹊径,使用模态视图
使用模态视图可以不受这种根视图控制器优先级的限制。这个也很容易理解,模态弹出的视图控制器是隔离出来的,不受根视图控制的影响。具体的设置和普通视图器代码相同,这里就不累述了;
六、实现需求:项目主要界面竖屏,部分界面横屏
这其实也是一个我们做屏幕旋转最常见的需求,在根据上面的讲述之后,我们实现这个需求会很容易,但是具体的实现却有着不同的思路,我在这里总结了两种方法:
方法1:使用基类控制器逐级控制
- 开启全局权限设置项目支持的旋转方向;
- 根据第五节中的方法1,自定义标签控制器和导航控制器来设置屏幕的自动旋转;
- 自定义基类控制器设置不支持自动转屏,并默认只支持竖屏;
- 对项目中需要转屏幕的控制器开启自动转屏、设置支持的旋转方向并设置默认方向;
- 在
Applegate
文件中增加一个用于记录当前屏幕是否横屏的属性; - 需要横屏的界面,进入界面后强制横屏,离开界面时恢复竖屏;
七、默认横屏无效的问题
在上面的项目中,我们可能会遇到一个关于默认横屏的问题,把它拿出来细说一下。
我们项目中有支持竖屏的界面A
,也有支持横竖屏的界面B
,而且界面B
需要进入时就显示横屏。从界面A
到界面B
中,如果我们使用第五节中的方法1会遇到无法显示默认横屏的情况,因为没有旋转设备,shouldAutorotate
就没被调用,也就没法显示我们需要的横屏。这里有两个解决方法:
方法1:在自定义导航控制器中增加以下方法
这个方法的缺点是,原理上利用弹出模态视图来调用转屏,造成切换界面的时候有闪烁效果,体验不佳。所以这里也只是提供一种思路,不推荐使用;
方法2:在需要默认横屏的界面里设置,进入时强制横屏,离开时强制竖屏
关于这种使用,这个具体可以参考第五节中的demo2
注意:两种方法不可同时使用
八、关于旋转后的适配问题
屏幕旋转的实现会带来相应的UI
适配问题,我们需要针对不同方向下的界面重新调整视图布局。首先我们要能够监测到屏幕旋转事件,这里分为两种情况:
当发生转屏事件的时候,下面的UIViewControoller
方法会监测到视图View
的大小变化,从而帮助我们适配
从注释里可以看出此方法在屏幕旋转的时候被调用,我们使用时候也应该首先调用super
方法,具体代码使用示例如下:
//屏幕旋转之后,屏幕的宽高互换,我们借此判断重新布局
//横屏设置,为防止遮挡键盘,调整输入视图的高度
如果是类似于表视图的单元格,要监测到屏幕变化实现适配,我们需要用到layoutSubviews
方法,因为屏幕切换横竖屏时会触发此方法,然后我们根据状态栏的位置就可以判断横竖屏了,代码示例如下:
有时项目需要从App
启动就默认是横屏,这里有个很方便的方法,就是我们在Device Orientation
属性配置里设置如下:
但是只这样处理的话,会让项目只支持横屏,所以我们可以在Appdelegate
里再次调整我们所支持的方向,方法已经说过,这里就不累述了;
关于屏幕旋转的使用大致总结到这里了,如果存在疏漏与错误欢迎路过的朋友指正!谢谢~