iPhone屏幕旋转机制详解

主要说一下本人对iOS6.0及以前版本中对屏幕旋转的操作:包括重力感应旋转和强制旋转。

首先说一下重力感应引起的屏幕旋转。

在iOS6.0以前,只需要UIViewController的子类重载 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation函数即可实现屏幕是否旋转。该方法返回YES,便支持四个方向的旋转。要指定特定的方向旋转,就返回  toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft 之类的值,具体哪个方向,根据你的需要而定。该方法默认是返回NO的,即不支持旋转。但是在iOS6.0及以后,- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation方法被置为Deprecated,该方法也不会被调用了。取而代之的是 -(BOOL)shouldAutorotate方法和 - (NSUInteger)supportedInterfaceOrientations方法。前者设置屏幕是否可以旋转,后者设置屏幕允许旋转的方向。前者默认返回YES,后者默认返回除倒置外的三个方向。即默认情况下是允许屏幕旋转的。具体用法是-(BOOL)shouldAutorotate只返回YES或NO, - (NSUInteger)supportedInterfaceOrientations方法返回指定的方向,比如 UIInterfaceOrientationMaskAllButUpsideDown。但是这两个方法,在iOS6.0以前是不会被调用的。只适合iOS6.0及以后。


再说一下屏幕强制旋转的实现方法。

该方法使用的是 http://blog.csdn.net/starryheavens/article/details/8083644 中的第一种方法。通过获取系统电池的方向从而得到屏幕的方向,然后通过改变电池的方向来改变状态栏的方向。但这样做的一个弊端是需要人为的改变view的transform属性,要自己维护view上面控件在旋转之后的布局。

具体办法:

   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的属性,而每次改变之前没有重置的话,你会发现后来的改变和你想要的发生变化了,不是你真正想要的结果。

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

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

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

3.设置我们的View的中心点
     CGPointcenter = 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:UIDeviceOrientationLandscapeRightanimated:YES];
CGFloat duration = [UIApplicationsharedApplication].statusBarOrientationAnimationDuration;(获取当前电池条动画改变的时间)
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:duration];

       //在这里设置view.transform需要匹配的旋转角度的大小就可以了。

        [UIView commitAnimations];


以上是转自http://blog.csdn.net/starryheavens/article/details/8083644 的内容,虽然代码有点儿问题,但是那种思路是正确的。

按照以上的思路,在iOS6.0以前还要使 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation函数返回YES,才能实现屏幕的强制旋转。而且此时屏幕的强制旋转与屏幕的重力感应旋转可以自由切换。

在iOS6.0中,要使-(BOOL)shouldAutorotate返回YES,而且(必须)要使- (NSUInteger)supportedInterfaceOrientations方法返回0(这是关键)才能使屏幕强制旋转到你指定的方向。但是这就出现了一个问题,由于在iOS6.0中,要使屏幕响应重力感应的旋转,那么- (NSUInteger)supportedInterfaceOrientations函数要返回非零值,这样就使得屏幕重力感应的旋转与强制旋转两种效果不能兼得。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值