闲来无事研究了一下屏幕旋转的问题
说到屏幕旋转问题不得先说一句,做项目尽量还是优先使用storyboard、IB因为有了autolayout的约束布局为基础再去做屏幕旋转需要的视图布局适配就相对来说简单容易很多。
好了,闲话不多说,开始今天要说的问题。
首先,想要实现单个屏幕旋转有两个重要的方法需要在viewcontroller里重写
使用模式如下:
//支持设备自动旋转
- (BOOL)shouldAutorotate{
returnYES;
}
//支持横竖屏显示
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
returnUIInterfaceOrientationMaskAll;
}
如果你以为这样就会实现屏幕的旋转,那么你还是too young.
想要在项目中使用屏幕旋转,需要注意一下几点
1、首先确保总开关打开,要不然有可能项目崩溃。 例如你想让某个视图支持横屏,然后你这样写道
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
returnUIInterfaceOrientationMaskLandscape;
}
这样就崩溃了,因为你项目根本就不支持横屏,言归正传,首先打开总开关(项目默认是打开的)
target -> General -> device orientation
打开开关你的项目就具备了屏幕旋转的权限。
2、当你做了第一步后发现确实可以屏幕确实可以旋转了,但是好像屏幕旋转不受你控制,你需要的仅仅是某个或某几个页面能旋转,但是现在全都能旋转,这怎么办呢,现在我们需要了解一下旋转的机制。
如果你想要支持屏幕旋转的controller为rootcontroller 那这样用,没毛病,但是一般情况下不会这样。
如果你想要controller支持旋转,那么你需要保证它的上一级也支持相应的旋转,通常情况下我们的controller都是在NavController 的栈里边,所以一般的我们的controller的上一级都是NavController,所以我们要设置NavController屏幕旋转
//支持设备自动旋转
- (BOOL)shouldAutorotate{
return YES;
}
//支持横竖屏显示
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAll;
}
但是问题来了,有这么一种场景,NavController栈里边有好几个controller,可能你只需要某一个controller支持,而其他的不支持,最好的办法是获取栈最顶端的controller对旋转的支持状态,修改后如下
//支持横竖屏
- (BOOL)shouldAutorotate{
return [self.viewControllers.lastObjectshouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return [self.viewControllers.lastObjectsupportedInterfaceOrientations];
}
由于controller默认是开启的状态,所以每一个不需要旋转的屏幕的controller都要写上这么一句
//屏幕旋转
//支持设备自动旋转
- (BOOL)shouldAutorotate{
returnNO;
}
是不是麻烦?简单一点都办法就是创建一个controller的基类BaseViewController每个controller都继承BaseViewController ,在BaseViewController中重写- (BOOL)shouldAutorotate 方法默认关闭,这样做的坏处就是增加了项目代码的耦合度,因为BaseViewController是比较基础的,稍有改动就可能会对项目有很大的影响,利弊自己权衡。
到这里你可能会想那项目中是以TabbarController 为Root controller的话怎么办?思考一下,其实TabbarController即为NavController 的上一级,根据NavController的逻辑我们可以写出下面的代码,一举解决这个问题。
//支持横竖屏
- (BOOL)shouldAutorotate{
returnself.selectedViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return [self.selectedViewControllersupportedInterfaceOrientations];
}
说了这么多其实最主要的就是想清楚项目中controller的层层之间的关系,然后再去做相应的设置,最终你会实现你想要的。
3、最后附上,进入某controller就让它旋转到某个方向的利器,经本人验证,可用,客官放心用
NSNumber *value = [NSNumbernumberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevicecurrentDevice]setValue:valueforKey:@"orientation"];
暂时就这么多内容,以后有新的内容会继续更新。
PS: 很多人问我有没有demo,特此写了一个swift版的 demo,demo不重要重要的是理解屏幕旋转的逻辑
demo地址:https://github.com/liutongchao/Orientation
有问题欢迎指正以及互相探讨 -- LC.West