浅谈iOS 屏幕方向那点事儿

一般的应用,只会支持竖屏正方向一个方向,支持多个屏幕方向的应用还是比较少的。

不过我在工作的项目中,跟这个屏幕方向接触比较多,因为我们是一个有界面的 SDK,要让接入方接入的,一开始做没什么经验,考虑到接入方本身的屏幕方向可能是多种的,所以我们直接上来就支持四个方向,然后就是各种转屏的问题,90度旋转、180读旋转、270度旋转,测试手都快转断了。

后来觉的根本没必要,浪费了很多时间在解决屏幕方向的问题上,后来就简化到让接入方直接设置支持某个方向了。

一般的应用不用搞的这么的复杂,只要支持一两个屏幕方向就可以了。我也做一下跟屏幕方向有关的几点总结,希望能帮到一些开发者!

系统屏幕方向枚举

通过查看文档,用于控制系统屏幕方向的枚举如下:

// iOS 6 之前用于控制屏幕方向的枚举
typedef enum {
  UIInterfaceOrientationPortrait      = UIDeviceOrientationPortrait,
  UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
  UIInterfaceOrientationLandscapeLeft   = UIDeviceOrientationLandscapeRight,
  UIInterfaceOrientationLandscapeRight   = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;

// iOS 6 及之后版本用于控制屏幕方向的枚举
typedef enum {
  UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
  UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
  UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
  UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
  UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
  UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
   UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
  UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
   UIInterfaceOrientationMaskLandscapeRight),
} UIInterfaceOrientationMask;

可以发现:

  • iOS 6 及之后版本使用的 UIInterfaceOrientationMask 类型来控制屏幕屏幕方向,该类型也新增加了几个枚举取值,可用一个枚举取值来代表多个屏幕方向。
  • 四个基本屏幕方向(上、下、左、右)中,UIInterfaceOrientationMask = (1 << UIInterfaceOrientation),所以,如果你的应用中需要动态的将 UIInterfaceOrientation 类型转换成 UIInterfaceOrientationMask 类型的话,只需做一下上面的转换即可,不需要通过 switch 来判断再转换。

怎么控制屏幕方向

在 iOS 的应用中,有多种方式可以控制界面的屏幕方向,有全局的,有针对 UIWindow 中界面的控制,也有针对单个界面。

单个界面控制

iOS 6之前

在 iOS 6 之前,单个界面的屏幕方向控制,都使用 UIViewController 类中的这个方法:

// 是否支持旋转到某个屏幕方向
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
  return ((toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) |
       (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft));
}

默认情况下,此方法只有参数为 UIInterfaceOrientationPortrait 时,返回值才为真,即默认只支持竖屏向上。上面的例子中,表示支持横屏向右及横屏向左两个方向。

iOS 6及之后的版本

在 iOS 6 及之后的版本,单个界面的屏幕方向控制,要使用 UIViewController 在 iOS 6.0 中新增加的两个方法:

// 是否支持转屏
- (BOOL)shouldAutorotate
{
  return YES;
}

// 支持的屏幕方向,此处可直接返回 UIInterfaceOrientationMask 类型
// 也可以返回多个 UIInterfaceOrientationMask 取或运算后的值
- (NSUInteger)supportedInterfaceOrientations
{
  return UIInterfaceOrientationMaskLandscape;
}

其中 - supportedInterfaceOrientations 方法在 iPad 中默认取值为 UIInterfaceOrientationMaskAll,即默认支持所有屏幕方向;而 iPhone 跟 iPod Touch 的默认取值为 UIInterfaceOrientationMaskAllButUpsideDown,即支持除竖屏向下以外的三个方向。

在设备屏幕旋转时,系统会调用 - shouldAutorotate 方法检查当前界面是否支持旋转,只有 - shouldAutorotate 返回 YES 的时候,- supportedInterfaceOrientations 方法才会被调用,以确定是否需要旋转界面。

UIWindow中的界面控制(iOS 6及以上版本才有效)

在 iOS 6 中,UIApplicationDelegate 协议中添加了一个可以指定 UIWindow 中的界面的屏幕方向的方法:

- (NSUInteger)application:(UIApplication *)application
    supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
  return UIInterfaceOrientationMaskLandscape;
}

此方法的默认值为 Info.plist 中配置的 Supported interface orientations 项的值。

一般我们都不会创建其他的 UIWindow,所以通过这个方法,也可以达到全局控制。

全局控制

在应用的 Info.plist 文件中,有一个 Supported interface orientations 的配置,可以配置整个应用的屏幕方向,如下图:

此配置其实跟工程中 Target 的 Summary 界面中的 Supported interface orientations 配置是一致的,修改任意一边,另一个边都会同步的修改。

并且,应用在启动时,会使用 Info.plist 中的 Supported interface orientations 项中的第一个值作为启动动画的屏幕方向。按照此处截图的取值,第一个取值为 Portrait(top home button),即竖屏反方向,所以此应用在启动时,会使用竖屏反方向显示启动动画。

多种控制共存的规则

  • 一个界面最后支持的屏幕方向,是取 (全局控制 ∩ UIWindow 中的界面控制 ∩ 单个界面控制) 的交集,如果全局控制支持所有屏幕方向,UIWindow 中的界面控制支持横屏,当个界面中只是支持横屏向右,那么最后界面只会以横屏向右显示,并且不支持旋转到其他的方向。
  • 如果以上三种控制支持的屏幕方向最后的交集为空,iOS 5 跟 iOS 6 的处理有点不同,在 iOS 6 下,甚至会直接抛出 UIApplicationInvalidInterfaceOrientationException 的异常,然后直接崩溃,所以还是要保持这三个值的交集为非空。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS如何获取屏幕宽高、设备型号、系统版本信息

    介绍 在我学习Android开发的时候,觉得设备适配是件很头疼的事情,android的设备太多了,那时就很羡慕iOS开发的人不用操心适配的问题,而当我开始学习iOS开发后,iOS的屏幕也开始多种多样了起来...于是也得做适配了,sad... 之前也研究过,这里把我的方法记录下来,本文介绍三个常用的设备信息获取方式: 获取屏幕的宽高.用于在设置控件位置的时候计算相对屏幕的距离 获取设备的型号.5s和6+的屏幕大小相差很远,相应的控件位置.大小都需要做出调整,不然就会出现在6+上显得很空旷或者在5s

  • iOS实现屏幕亮度和闪光灯控制的实例代码

    这两天学习了iOS屏幕亮度和闪光灯控制,所以,今天添加一点小笔记. 所用涉及框架:AVFoundation框架和ImageIO 读取屏幕亮度:[UIScreen mainScreen].brightness; 设置屏幕亮度:[[UIScreen mainScreen] setBrightness:0.5]; 获取环境亮度主要代码: - (void)getTorch { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMedi

  • iOS屏幕根据键盘自动变化高度

    一.效果图 二.代码 ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UITextFieldDelegate> @end ViewController.m #import "ViewController.h" #define W [UIScreen mainScreen].bounds.size.width #define H [UISc

  • iOS 中根据屏幕宽度自适应分布按钮的实例代码

    下载demo链接:https://github.com/MinLee6/buttonShow.git 屏幕摆放的控件有两种方式,一种根据具体内容变化,一种根据屏幕宽度变化. 下面我分别将两个方式,用代码的方式呈现: 1:根据具体内容变化 // // StyleOneViewController.m // buttonShow // // Created by limin on 15/06/15. // Copyright © 2015年 信诺汇通信息科技(北京)有限公司. All rights

  • iOS屏幕旋转与锁屏的示例代码

    在做视频开发时遇到屏幕旋转问题,其中涉及到 StatusBar. UINavigationController.UITabBarController .UIViewcontroller . 在设备锁屏下的整体效果图 iOS-旋转.gif 主要涉及以下4点: 横竖屏的旋转 屏幕旋转相应改变视图位置 旋转时状态栏的隐藏与显示 锁屏 1.横竖屏旋转 第1步: -(UIInterfaceOrientationMask)application:(UIApplication *)application su

  • iOS中屏幕亮度与闪光灯控制详解

    本文主要介绍的是关于iOS屏幕亮度与闪光灯控制的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 所用涉及框架:AVFoundation框架和ImageIO 读取屏幕亮度: [UIScreen mainScreen].brightness; 设置屏幕亮度: [[UIScreen mainScreen] setBrightness:0.5]; 获取环境亮度主要代码: - (void)getTorch { AVCaptureDevice *device = [AVCaptureDevice

  • IOS开发中键盘输入屏幕上移的解决方法

    在IOS开法中经常会遇到键盘遮挡屏幕的事情(比如输入账号密码验证码等等),就使得原本都不大的屏幕直接占了一半甚至更多的位置,这倒无所谓,关键是挡住了下面的按钮.这样的话按钮的事件也就触发不了,最好的解决办法就是当输入这些信息的时候让整个屏幕上移一个键盘的位置,或者上移到指定的位置. 首先一般输入的话都用的是UITextField,所以要监听用户什么时候开始输入和什么时候结束输入,直接设置代理代理就行了,要遵受 UITextFieldDelegate协议. //遵循协议 @interface Vi

  • iOS屏幕适配开发实用技巧

    一.旋转处理 第一步:注册通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeFrames:) name:UIDeviceOrientationDidChangeNotification object:nil]; 第二步:处理接收事件 -(void)changeFrames:(NSNotification *)notification{ NSLog(@"change notifica

  • iOS实现一个可以在屏幕中自由移动的按钮

    本文主要给大家介绍了利用iOS实现一个可以在屏幕中自由移动的按钮的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍. 效果图如下: 其实实现很简单,只需要写.m就可以了 示例代码 #import "CrossBtnVC.h" @interface CrossBtnVC () { CGPoint beginPoint; CGFloat rightMargin; CGFloat leftMargin; CGFloat topMargin; CGFloat bottomM

  • 关于iOS屏幕旋转的一些注意事项

    前言 最近有个需求,是在App中有一个查看文件的页面,由于查看文件横屏会更方便阅读,所以boss说要让这个页面可以横屏.之前都没有接触过横屏的具体实现方法,一开始走了不少弯路,而且各种bug.在这里把遇到的问题分享一下,希望对大家有点帮助. 要让你的APP支持旋转,你需要进行如下几个步骤 1. 全局配置 在工程->TARGETS->General->Deployment Info中配置 在AppDelegate中配置 - (UIInterfaceOrientationMask)appli

  • iOS实现控制屏幕常亮不变暗的方法示例

    前言 最近在做一个开发,有一个地方同步音乐文件,有时间会出现屏幕熄灭状态,导致同步出现断开,现在决定在同步时保持屏幕常亮,其实很多时候我们需要保持屏幕高亮,下面就来给大家介绍一个实现的方法,但是要记得在适当的时候关闭常亮 示例代码 //设置屏幕常亮 [UIApplication sharedApplication].idleTimerDisabled = YES; //取消设置屏幕常亮 [UIApplication sharedApplication].idleTimerDisabled = N

随机推荐