在 iPhone 应用里,有时我们想强行把显示模式从纵屏改为横屏(反之亦然),特别是需要展示音频,视频播放器的时候需要进行横竖屏切换,下面做下横竖屏总结,如有不全面之处欢迎留言补充。

目前横竖屏旋转方式分为手动和自动

手动旋转
手动旋转也有2种方式,一种是直接设置 UIDevice 的 orientation,但是这种方式不推荐,上传appStore有被拒的风险:

复制代码 代码如下:

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {  
    [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait];  
}

第二种是假旋转,并没有改变 UIDevice 的 orientation,而是改变某个view的 transform,利用 CGAffineTransformMakeRotation 来达到目的,比如:

复制代码 代码如下:

self.view.transform = CGAffineTransformMakeRotation(M_PI/2)  

下面讲解采用第二种方式的各版本手动旋转:
思想是首先设置 statusBarOrientation,然后再改变某个view的方向跟 statusBarOrientation 一致!

那既然是旋转,最少也得有2个方向,那么还是少不了上面说的那个硬性条件,先在plist里面设置好所有可能需要旋转的方向。既然是手动旋转,那么就要关闭自动旋转:

view.transform一般是View的旋转,拉伸移动等属性,类似view.layer.transform,区别在于View.transform是二维的,也就是使用仿射的办法通常就是带有前缀CGAffineTransform的类(可以到API文档里面搜索这个前缀的所有类),而view.layer.transform可以在3D模式下面的变化,通常使用的都是前缀为CATransform3D的类。

这里要记住一点,当你改变过一个view.transform属性或者view.layer.transform的时候需要恢复默认状态的话,记得先把他们重置可以使用view.transform = CGAffineTransformIdentity,或者view.layer.transform = CATransform3DIdentity,假设你一直不断的改变一个view.transform的属性,而每次改变之前没有重置的话,你会发现后来的改变和你想要的发生变化了,不是你真正想要的结果。

好了,上面介绍了旋转的属性,接下来就是关键了。官方提供了一个办法就是查看当前电池条的状态UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;通过这个办法,你可以知道当前屏幕的电池条的显示方向,而且你还可以强制设置他的显示方向,通过设置这个属性就OK了,可以选择是否动画改变电池条方向。有了这两个那我们就可以任意的改变我们想要的显示方式了。

1.获取当前电池条的方向UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation

2.获取当前屏幕的大小CGRect frame = [UIScreen mainScreen].applicationFrame;

3.设置我们的View的中心点
CGPoint center = CGPointMake(frame.origin.x + ceil(frame.size.width/2), frame.origin.y + ceil(frame.size.height/2));

4.根据当前电池条的方向,获取需要旋转的角度的大小。通常

if (orientation == UIInterfaceOrientationLandscapeLeft) {
return CGAffineTransformMakeRotation(M_PI*1.5);
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
return CGAffineTransformMakeRotation(M_PI/2);
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
return CGAffineTransformMakeRotation(-M_PI);
} else {
return CGAffineTransformIdentity;
}

5.可以动画的改变我们view的显示方式了
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeRight animated:YES];

CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;(获取当前电池条动画改变的时间)
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
//在这里设置view.transform需要匹配的旋转角度的大小就可以了。
[UIView commitAnimations];

复制代码 代码如下:

- (BOOL)shouldAutorotate{  
        return NO;  
}

手动触发某个按钮,调用方法,这个方法的实现如下:

复制代码 代码如下:

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];  
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);  
self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320); 
 

注意:
1. 只需要改变self.view.transform,那么self.view的所有subview都会跟着自动变;其次因为方向变了,所以self.view的大小需要重新设置,不要使用self.view.frame,而是用bounds。
2. 如果shouldAutorotate 返回YES的话,下面设置setStatusBarOrientation 是不管用的!setStatusBarOrientation只有在shouldAutorotate 返回NO的情况下才管用!

自动旋转设置:
控制某个viewController旋转并不是像IOS5或者IOS4一样在这个viewController里面重写上面那2个方法,而是需要在这个viewController的rootViewController(根视图控制器)里面重写,怎么解释呢?就是最前面的那个viewController,直接跟self.window接触的那个controller,比如以下代码:

复制代码 代码如下:

UIViewController *viewCtrl = [[UIViewController alloc] init];  
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:viewCtrl];  
if ([window respondsToSelector:@selector(setRootViewController:)]) {  
    self.window.rootViewController = navCtrl;  
} else {  
    [self.window addSubview:navCtrl.view];  
}  

如果需要设置viewCtrl的旋转,那么不能在UIViewController里面重写shouldAutorotate和supportedInterfaceOrientations方法,而是需要在navCtrl里面设置,又因为UINavigationController是系统控件,所以这里需要新建一个UINavigationController的子navigationController的子类,然后在里面实现shouldAutorotate和supportedInterfaceOrientations方法,比如:

复制代码 代码如下:

-(NSUInteger)supportedInterfaceOrientations{  
    return UIInterfaceOrientationMaskAllButUpsideDown;  
}  
  
- (BOOL)shouldAutorotate{  
    return YES;  

eg1:如果上面的例子是self.window.rootViewController = viewCtrl,而不是navCtrl,那么上面的那2个控制旋转的方法就应该写在UIViewController里面!

eg2:如果viewCtrl又pushViewController到viewCtrl2,需要设置viewCtrl2的旋转,怎么办呢? 还是在navCtrl里面控制,因为viewCtrl和viewCtrl2的rootViewController都是navCtrl,一般的写法都是

复制代码 代码如下:

UIViewController *viewCtrl2 = [[UIVewController alloc] init];  
[self.navigationController.navigationController pushViewController:viewCtrl2 animated:YES]; 

所以要控制一个UINavigationController push到的所有viewController的旋转,那么就得在navCtrl里面区分是哪个viewController,以便对他们一一控制!同样如果rootViewController是UITabbarController,那么需要在子类化的UITabbarController里面重写那2个方法,然后分别控制!

但是有时候我初始化UINavigationController的时候,并不知道所有我所有需要push到的viewController,那么这里有一个通用的方法,就是让viewController自己来控制自己,首先在navCtrl里面的实现方法改为以下方式:

复制代码 代码如下:

- (BOOL)shouldAutorotate    
{    
    return self.topViewController.shouldAutorotate;    
}    
    
- (NSUInteger)supportedInterfaceOrientations    
{    
    return self.topViewController.supportedInterfaceOrientations;    
}  

全部调用self.topViewController,就是返回当前呈现出来的viewController里面的设置,然后在viewCtrl、viewCtrl2等等这些viewController里面重写shouldAutorotate和supportedInterfaceOrientations,以方便设置每个viewController的旋转

eg3:如果viewCtrl 是 presentModalViewController 到 viewCtrl3,那么viewCtrl3的旋转设置就不在navCtrl里面了!如果presentModalViewController的viewController是navController、tabbarController包装过的viewCtrl3,那么就应在新包装的navController、tabbarController里面设置,如果是直接presentModalViewController到viewCtrl3,那么就在viewCtrl3里面设置

通过setOrientation:的办法强制性的旋转到一个特定的方向。

注意:Apple在3.0以后都不支持这个办法了,这个办法已经成为了私有的了,但是要跳过App Stroe的审核,需要一点巧妙的办法。

不要直接调用[[UIDevice currentDevice] setOrientation: UIInterfaceOrientationLandscapeRight]这样的办法来强制性的横屏,这样导致你的程序是很难通过App Store审核的。但是你可以选择使用performSelector的办法来调用它。具体就几行代码如下:

//强制横屏
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice] performSelector:@selector(setOrientation:)
withObject:(id)UIInterfaceOrientationLandscapeRight];
}

总结:如果第一种办法可以满足你需要的话,最好使用第一种办法,因为那个上 App Store肯定没问问题,但是第二种的话是需要冒风险的,但是如果你的结构太复杂了,导致使用第一种办法人为很难控制的话,可以尝试简单的使用第二种办法。

iOS屏幕旋转,强制横竖屏相关推荐

  1. iOS开发屏幕旋转锁定横竖屏解决方法

    iOS开发屏幕旋转锁定横竖屏解决方法 使用场景: 公司最近产品,有两个界面是横屏的,其他的界面是竖屏的.针对这个需求,也调试了一段时间.在网上也查找了不少资料. 解决的方案也是有的,但是都是需要在导航 ...

  2. iOS 屏幕旋转问题总结

    1.两个Orientation 1.1设备的物理方向(UIDeviceOrientation) typedef NS_ENUM(NSInteger, UIDeviceOrientation) {UID ...

  3. ios屏幕旋转学习笔记

    加速计是整个IOS屏幕旋转的基础,依赖加速计,设备才可以判断出当前的设备方向,IOS系统共定义了以下七种设备方向: typedef NS_ENUM(NSInteger, UIDeviceOrienta ...

  4. android重力感应横竖屏,Android开发 apk强制横竖屏

    Android开发 apk强制横竖屏 (2014-05-02 10:57:50) 标签: 杂谈 全屏 在Activity的onCreate方法中的setContentView(myview)调用之前添 ...

  5. iOS开发:App横竖屏设置问题

    在iOS开发中,难免会遇到关于手机屏幕是否切换横竖屏的问题,比如一个App整体的界面都需要竖屏显示,那么只用在Xcode里面的General里面的Deployment Info里面把横竖屏选项勾选去掉 ...

  6. ios键盘横屏_iOS横竖屏旋转及其基本适配方法 转

    目录 一.最让人纠结的三种枚举 二.两种屏幕旋转的触发方式 三.屏幕旋转控制的优先级 四.开启屏幕旋转的全局权限 五.开启屏幕旋转的局部权限(视图控制器) 六.实现需求:项目主要界面竖屏,部分界面横屏 ...

  7. iOS屏幕旋转 浅析

    一.两种orientation 了解屏幕旋转首先需要区分两种orientation 1.device orientation 设备的物理方向,由类型UIDeviceOrientation表示,当前设备 ...

  8. iOS屏幕旋转及其基本适配方法

    屏幕旋转示例.jpeg 前段时间抽空总结了一下iOS视频播放的基本用法,发现这其中还有一个我们无法绕过的问题,那就是播放界面的旋转与适配.的确,视频播放与游戏类型的App经常会遇到这个的问题.由于至今 ...

  9. iOS屏幕旋转那些事

    前些日子处理了一些关于页面中的屏幕旋转的事情,需要根据某个页面的不同旋转方向去做不同的处理,现在再次总结一下,以在心里有个系统的体系,也可以当成工具文章查询. 首先来看第一个方法: [UIDevice ...

最新文章

  1. Style Intelligence 10特点之用户自定义报表
  2. 升级之后的BCH将推动游戏业更上一层楼
  3. python各种文件数据的读取
  4. Linux目录结构FHS
  5. [YTU]_2428(C语言习题 计算该日在本年中是第几天)
  6. 深入Lock锁底层原理实现,手写一个可重入锁
  7. 一种抑制undershoot/overshoot锐化算法介绍
  8. python中变量名存储在哪里_python – 如何在内部存储和映射变量名称?
  9. Linux less命令:查看文件内容
  10. 【elasticsearch】Failed Elasticsearch bulk request: request retries exceeded max retry timeout
  11. [面试] 算法(一) —— Str2Int
  12. Away3D 的实体收集器流程2
  13. spring系统学习:day4--Spring工厂
  14. VS2010安装部署成.NET 2.0过程的几个问题
  15. Hashmap实现原理及hash冲突(碰撞)解决方法
  16. Android 开发环境搭建实验报告
  17. 苹果笔记本能玩英雄联盟吗_等了5年的英雄联盟手机版,今天终于能玩了
  18. phigros测试版软件头像,Phigros背景头像怎么用
  19. 【OMNeT++】ALOHA协议仿真中的channelUtilization
  20. hololens凝视物体、单击双击、语音控制、蓝牙

热门文章

  1. language model with pointer network
  2. 如何用php脚本抢东西,如何用JS代码实现网页抢购功能
  3. 冷不丁的来了个入职通知……感觉对方可能把我给忘了 ◎◎
  4. 2022-2028全球与中国手敲式乐器市场现状及未来发展趋势
  5. 如何实现类似CAD的命令系统
  6. 453_J1939命令地址PGN 65240(FED8)的使用
  7. 7年java只会crud,LICENSE · 只会CRUD/javashare - Gitee.com
  8. 百度的17年产品史——突围、霸权、迷失、焦虑与变革
  9. 「清华名师讲坛」推荐
  10. 计算机辅助测试技术最近的发展,CAT_计算机辅助测试_技术_第六讲_CAT的发展_郑叔芳...