iOS----应用的旋转---Orientations
此博文主要针对IOS应用, 是屏幕旋转相关问题的一个总结. 主要内容有:
- IOS5,6,7不同版的适配.
- 强制旋转和自动旋转.
- QQ : 1101819159
- 邮箱: GeekiVan@aliyun.com
- 作者: Magic-Van.
- 时间: 2016-11-25
改变Orientation的三种途径
这里, 咱们主要理清一下: 到底有哪些设置可以改变屏幕旋转特性. 这样:
- 出现任何问题我们都可以从这几个途径中发现原因.
- 灵活应付产品经理的各种需求.
首先我们得知道:
- 当手机的重力感应打开的时候, 如果用户旋转手机, 系统会抛发
UIDeviceOrientationDidChangeNotification
事件. - 您可以分别设置
Application
和UIViewcontroller
支持的旋转方向.Application
的设置会影响整个App,UIViewcontroller
的设置仅仅会影响一个viewController
(IOS5和IOS6有所不同,下面会详细解释). - 当
UIKit
收到UIDeviceOrientationDidChangeNotification
事件的时候, 会根据Application
和UIViewcontroller
的设置, 如果双方都支持此方向, 则会自动屏幕旋转到这个方向. 更code的表达就是, 会对两个设置求与,得到可以支持的方向. 如果求与之后,没有任何可支持的方向, 则会抛发UIApplicationInvalidInterfaceOrientationException
异常.
Info.plist设置
在App的Info.plist里设置:
key | xcode name | Summary | avilable value |
---|---|---|---|
UIInterfaceOrientation | initial interface orientation | Specifies the initial orientation of the app’s user interface. | UIInterfaceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight |
UISupportedInterfaceOrientations | Supported interface orientations | Specifies the orientations that the app supports. | UIInterfaceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight |
在Info.plist中设置之后,这个app里所有的viewController
支持的自动旋转方向都只能是app支持的方向的子集.
UIViewController
IOS6 and above
supportedInterfaceOrientations
在IOS6及以上的版本中, 增添了方法UIViewController.supportedInterfaceOrientations
. 此方法返回当前viewController
支持的方向. 但是, 只有两种情况下此方法才会生效:
- 当前
viewController
是window
的rootViewController
. - 当前
viewController
是modal
模式的. 即, 此viewController
是被调用presentModalViewController
而显示出来的.
在以上两种情况中,UIViewController.supportedInterfaceOrientations
方法会作用于当前viewController
和所有childViewController
. 以上两种情况之外, UIKit
并不会理会你的supportedInterfaceOrientations
方法.
举个栗子:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}
如果某个viewController
实现了以上方法. 则, 此viewController
就支持竖方向和左旋转方向. 此viewController
的所有childViewController
也同时支持这两个方向, 不多不少.
preferredInterfaceOrientationForPresentation
此方法也属于UIViewController
. 影响当前viewController
的初始显示方向. 此方法也仅有在当前viewController
是rootViewController
或者是modal
模式时才生效.
shouldAutorotate
此方法,用于设置当前viewController
是否支持自动旋转. 如果,你需要viewController
暂停自动旋转一小会儿. 那么可以通过这个方法来实现.同样的, 此方法也仅有在当前viewController
是rootViewController
或者是modal
模式时才生效.
IOS5 and before
在IOS5和以前的版本中, 每个viewController
都可以指定自己可自动旋转的方向.(这样不是挺好么?苹果那帮工程师为啥要搞成这样...).
每当UIkit
收到UIDeviceOrientationDidChangeNotification
消息的时候, 就会用以下方法询问当前显示的viewController
支不支持此方向:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if ((orientation == UIInterfaceOrientationPortrait) ||
(orientation == UIInterfaceOrientationLandscapeLeft))
return YES;
return NO;
}
特别要注意的是:你必须至少要对一个方向返回YES
.(为难系统总不会有啥好事儿,你懂得).
UIView.transform
最后一个方法是设置UIView
的transform
属性来强制旋转.
见下代码:
//设置statusBar
[[UIApplication sharedApplication] setStatusBarOrientation:orientation];
//计算旋转角度
float arch;
if (orientation == UIInterfaceOrientationLandscapeLeft)
arch = -M_PI_2;
else if (orientation == UIInterfaceOrientationLandscapeRight)
arch = M_PI_2;
else
arch = 0;
//对navigationController.view 进行强制旋转
self.navigationController.view.transform = CGAffineTransformMakeRotation(arch);
self.navigationController.view.bounds = UIInterfaceOrientationIsLandscape(orientation) ? CGRectMake(0, 0, SCREEN_HEIGHT, SCREEN_WIDTH) : initialBounds;
需要注意的是:
- 当然我们可以对当前
viewController
进行旋转, 对任何view
旋转都可以.但是, 你会发现navigationBar
还横在那里. 所以, 我们最好对一个占满全屏的view
进行旋转. 在这里我们旋转的对象是self.navigationController.view
, 当然self.window
也可以, help yourself~ - 我们需要显式的设置
bounds
.UIKit
并不知道你偷偷摸摸干了这些事情, 所以没法帮你自动设置.
如何应付产品经理的需求
有了以上三把武器, 我想基本可以应付BT产品经理所有的需求了. 但是这里还有一些小技巧.
直接锁死
(略)
随系统旋转
IOS5及之前
对于IOS5及之前的版本, 只要在对每个viewController
重写shouldAutorotateToInterfaceOrientation
方法, 即可方便的控制每个viewController
的方向.
IOS6及以后
对于IOS6及以后的版本, 如果想方便的单独控制每个viewController
的方向. 则可以使用这样:
对于非
modal
模式的viewController
:- 如果不是
rootViewController
,则重写supportedInterfaceOrientations
,preferredInterfaceOrientationForPresentation
以及shouldAutorotate
方法, 按照当前viewController
的需要返回响应的值. - 如果是
rootViewController
,则如下重写方法:
- 如果不是
-(NSUInteger)supportedInterfaceOrientations
{
return self.topMostViewController.supportedInterfaceOrientations;
}
-(BOOL)shouldAutorotate
{
return [self.topMostViewController shouldAutorotate];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topMostViewController preferredInterfaceOrientationForPresentation];
}
-(UIViewController*)topMostViewController
{
//找到当前正在显示的viewController并返回.
}
显而易见, 我们巧妙的绕开了UIKit
只调用rootViewController
的方法的规则. 把决定权交给了当前正在显示的viewController
.
- 对于
modal
模式的viewController
. 则按照需要重写supportedInterfaceOrientations
,preferredInterfaceOrientationForPresentation
以及shouldAutorotate
方法即可.
强制旋转
有时候, 需要不随系统旋转, 而是强制旋转到某一个角度. 最典型的场景就是视频播放器, 当点击了全屏按钮的时候, 需要横过来显示.
- 对于IOS5及以前的版本, 可以用下面的方法:
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIInterfaceOrientationLandscapeRight;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
- 对于IOS6及以后的版本.
UIDevice.setOrientation
从隐藏变为移除.只能通过设置UIView.transform
的方法来实现.
iOS----应用的旋转---Orientations的更多相关文章
- iOS实现屏幕旋转
iOS实现屏幕旋转有两种方式 1. 应用本身支持 2. 手动旋转UIView (这种方式我没找到旋转 系统控件的方法 如:键盘.导航.UIAlertView) 如果你只是要把竖屏的播放器,做成支持横屏 ...
- iOS 图片裁剪 + 旋转
iOS 图片裁剪 + 旋转 之前分别介绍了图片裁剪和图片旋转方法 <iOS 图片裁剪方法> 地址:http://www.cnblogs.com/silence-cnblogs/p/6490 ...
- ios实现屏幕旋转的方法
1.屏蔽AppDelegate下面的屏幕旋转方法 #pragma mark - 屏幕旋转的 //- (UIInterfaceOrientationMask)application:(UIApplica ...
- 【iOS】屏幕旋转,屏幕自适应方向变化
1. iOS有四个方向的旋转,为了保证自己的代码能够支持旋转,我们必须首先处理一个函数: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInter ...
- 监听iOS检测屏幕旋转状态,不需开启屏幕旋转-b
-(void)rotation_icon:(float)n { UIButton *history_btn= [self.view viewWithTag:<#(NSInteger)#>] ...
- (转)ios限制控制器旋转
iOS屏幕旋转控制 iOS屏幕旋转控制(iOS6之后) iOS6之前,子控制器只要覆盖父类的shouldAutorotateToInterfaceOrientation:方法就能单独控制某 ...
- js 前端图片压缩+ios图片角度旋转
step1:读取选择的图片,并转为base64: function ImgToBase64 (e, fn) { // 图片方向角 //fn为传入的方法函数,在图片操作完成之后执行 var Orient ...
- iOS拍照图片旋转的问题
很久之前,遇到了这种情况,iOS某端拍照上传到服务器,其他iOS端从服务器下载该照片展示,发现图片逆时针旋转了90度.当时百度了一下,找到一段代码修正image方向,问题解决了,但没有深入理解底层原理 ...
- ios 关于屏幕旋转和屏幕晃动
内置加速计是智能手机最酷的特性之一,ios可以通过这个小设备知道用户握持手机的方式,以及用户是否移动了手机,ios使用加速计处理自动旋转,并且许多游戏都是用它作为控制机制,它还可以用于检测摇动和其他突 ...
随机推荐
- H5单页面手势滑屏切换原理
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...
- 使用 Roslyn 编译器服务
.NET Core和 .NET 4.6中 的C# 6/7 中的编译器Roslyn 一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为 ...
- Linux 江湖系列阶段性总结
引言 我使用 Linux 已经有很多年了,最开始接触 Linux 的时候是从 RedHat 9(没有 Enterprise),中途换过 N 个不同的发行版.多年前,我在 BlogJava 上面分享 J ...
- 冒泡,setinterval,背景图的div绑定事件,匿名函数问题
1.会冒泡到兄弟元素么? $(function(){ $("#a").click(function(){alert("a")}) $("#b" ...
- 利用XAG在RAC环境下实现GoldenGate自动Failover
概述 在RAC环境下配置OGG,要想实现RAC节点故障时,OGG能自动的failover到正常节点,要保证两点: 1. OGG的checkpoint,trail,BR文件放置在共享的集群文件系统上,R ...
- 设置tomcat远程debug
查看端口占用情况命令: netstat -tunlp |grep 8000 tomcat 启动远程debug: startup.sh 中的最后一行 exec "$PRGDIR"/& ...
- ASP.NET中常用的优化性能的方法
1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...
- 使用HttpClient的优解
新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...
- PHP static静态属性和静态方法
这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...
- 使用Microsoft的IoC框架:Unity来对.NET应用进行解耦
1.IoC/DI简介 IoC 即 Inversion of Control,DI 即 Dependency Injection,前一个中文含义为控制反转,后一个译为依赖注入,可以理解成一种编程模式,详 ...