IOS5,6,7不同版的适配. 强制旋转和自动旋转.

摘要:
以下是三种更改方向的方法:哪些设置可以更改屏幕旋转特性?这样,我们可以通过这些方式找到任何问题的原因,并灵活地满足产品经理的需求。首先,我们需要知道,当手机的重力传感器打开时,如果用户旋转手机,系统将抛出UIDeviceOrientationDidChangeNotification事件。您可以分别设置Application和UIViewcontrol

改变Orientation的三种途径

这里, 咱们主要理清一下: 到底有哪些设置可以改变屏幕旋转特性. 这样:

  • 出现任何问题我们都可以从这几个途径中发现原因.

  • 灵活应付产品经理的各种需求.

首先我们得知道:

  1. 当手机的重力感应打开的时候, 如果用户旋转手机, 系统会抛发UIDeviceOrientationDidChangeNotification 事件.

  2. 您可以分别设置Application和UIViewcontroller支持的旋转方向.Application的设置会影响整个App, UIViewcontroller的设置仅仅会影响一个viewController(IOS5和IOS6有所不同,下面会详细解释).

  3. 当UIKit收到UIDeviceOrientationDidChangeNotification事件的时候, 会根据Application和UIViewcontroller的设置, 如果双方都支持此方向, 则会自动屏幕旋转到这个方向. 更code的表达就是, 会对两个设置求,得到可以支持的方向. 如果求之后,没有任何可支持的方向, 则会抛发UIApplicationInvalidInterfaceOrientationException异常.

Info.plist设置

在App的Info.plist里设置:

key   xcode nameSummaryavilable valueUIInterfaceOrientationinitial interface orientationSpecifies the initial orientation of the app’s user interface.UIInterfaceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft,
UIInterfaceOrientationLandscapeRightUISupportedInterfaceOrientationsSupported interface orientationsSpecifies the orientations that the app supports.UIInterfaceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft,
UIInterfaceOrientationLandscapeRight

在Info.plist中设置之后,这个app里所有的viewController支持的自动旋转方向都只能是app支持的方向的子集.



UIViewControllerIOS6 and abovesupportedInterfaceOrientations

在IOS6及以上的版本中, 增添了方法UIViewController.supportedInterfaceOrientations. 此方法返回当前viewController支持的方向. 但是, 只有两种情况下此方法才会生效:

  1. 当前viewController是window的rootViewController.

  2. 当前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;

需要注意的是:

  1. 当然我们可以对当前viewController进行旋转, 对任何view旋转都可以.但是, 你会发现navigationBar还横在那里. 所以, 我们最好对一个占满全屏的view进行旋转. 在这里我们旋转的对象是self.navigationController.view, 当然self.window也可以, help yourself~

  2. 我们需要显式的设置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两个强制旋转屏幕的方法

  • Supporting Multiple Interface Orientations

免责声明:文章转载自《IOS5,6,7不同版的适配. 强制旋转和自动旋转.》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇实现checkbox全选、非全选、单选吉特仓储管理系统-ERP或WMS系统中常见术语下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于HTML5的iPad电子杂志横竖屏自适应方案

基于HTML5的iPad电子杂志横竖屏自适应方案 (转载自:http://www.yeeach.com/?p=1172) 基于HTML5来制作iPad电子杂志,横屏及竖屏自适应是个大问题,查找了半天资料,没有一篇像样的文章可供参考。将思路及例子分享一下。例子并不严谨和规范,仅供参考。 大致思路: 1、对横屏(portrait)和竖屏(landscape)情...

转载:Qt应用程序采用双屏显示的一些想法

 转载地址:https://www.cnblogs.com/ppffs/p/3186221.html 最近由于项目需要,采用Qt开发的程序要能够支持双屏显示,在网上调研了以下,发现网页http://www.ics.com/blog/whats-new-qt-5-qscreen-class#.Ud9mY4csnXB中对于Qt的多屏幕管理有一定论述,指出采用Q...

JS获取照片拍摄的角度属性,用于旋转控制

在微信里ios手机上传竖拍照片会自动旋转90度,与拍摄时的角度不同,所以需要处理: 1、使用EXIF.js可以获取到照片的拍摄属性: API 方法 名称 说明 EXIF.getData(img, callback) 获取图像的数据 能兼容尚未支持提供 EXIF 数据的浏览器获取到元数据。 EXIF.getTag(img, tag) 获取图...

移动端——JS(一)

javascript(简称js)语言在移动前端可以说必不可少,许多效果都是和js相关的,包括现在移动端的一些框架:jqmobi、jqtouch、sencha touch、jquerymobile等等。都是基于js编写的。 暂时不讨论这些框架,主要讨论一下部分常用的js事件在移动端的使用。举几个例子: 1、隐藏地址导航栏: <script> /...

移动端H5开发问题记录

1. 当弹出键盘时,会改变页面高度,影响页面样式     通过window.onsize事件可以控制键盘弹出或消失的时候的样式  var h = document.body.scrollHeight // 用onresize事件监控窗口或框架被调整大小,先把一开始的高度记录下来 window.onresize = function ()...

Android屏幕重力感应旋转

public class MainActivity extends AppCompatActivity {   private MyOrientoinListener myOrientoinListener; @Override protected void onCreate(Bundle savedInstanceState) {...