iOS - 强制横屏


一、正常方向旋转处理流程


要求旋转方向-》判断是否支持该方向-》判断是否支持旋转

注释:下文将“要求旋转的方向”称为pending方向。

 

1、判断支持的方向


系统会调用两个方法:

AppDelegate的application:supportedInterfaceOrientationsForWindow:(如果没有实现,info.plist中的Supported interface orientations作为代替)

当前视图控制器的supportedInterfaceOrientations(默认实现是除了向上的三个方向)

 

 

两个方法的重叠部分是支持的方向(有可能没有重叠的方向)。

 

注释:当前视图控制器指的是哪个?
举例:
rootvc:nav-(push)->child1=》当前视图控制器为nav
rootvc:nav-(push)->child1-(presented by child1)->child2=》当前视图控制器为child2
rootvc:nav-(push)->child1-(presented by nav)->child2=》当前视图控制器为child2

 

 

2、判断是否支持旋转


支持旋转:
如果有重叠的方向-》旋转;
如果没有重叠的方向-》崩溃

不支持旋转:有没有重叠的方向,都不旋转。

判断是否支持旋转的方法是当前视图控制器的shouldAutorotate

注意:如果得到的重叠的方向是竖屏,并且支持旋转,但是,要求旋转的方向是横屏,也会旋转到横屏方向。

 

二、触发方向旋转

 

  1. 用户旋转屏幕方向(方向锁没有锁),这是正常的方式;
  2. KVC的方式修改currentDevice的orientation属性,强制横屏就是使用的这个方式。

 

三、另当别论的modal动画

 

使用模态动画展示出来的视图控制器,展示时,系统会调用preferredInterfaceOrientationForPresentation方法,即使不使用上述两种方法旋转屏幕方向,一样可以达到旋转屏幕的效果(当然是在preferredInterfaceOrientationForPresentation的结果与当前屏幕方向不同的情况下)

 

四、键盘

 

键盘方向是preferredInterfaceOrientationForPresentation的结果,preferredInterfaceOrientationForPresentation默认是竖屏。

 

五、进入应用时,什么决定横竖屏

 

支持的方向只有横屏时,才横屏,不然都先竖屏,之后再根据屏幕方向,会旋转屏幕或者继续竖屏。

 

六、iOS系统不同版本兼容


没有研究iOS7的系统,只处理了iOS8和9的兼容问题。

iOS8下,使用push动画,如果使用第二种方法旋转屏幕不生效的话,可以在旋转之后,present一个横屏的空白视图控制器,再立即dismiss。

 

七、我的产品需求


阅读类应用:

  • 书架在内的绝大部分页面,只支持竖屏;
  • 阅读器是使用push动画展示的,支持横屏;
  • 从阅读器可以继续push出来设置、目录、搜索页面等,这些页面的方向与阅读器一致;
  • 搜索页面需要弹出键盘;
  • 设置页展示期间,可能需要present其他视图控制器,方向也与阅读器一致


实现方式:

  • info.plist里怎么设置方向都可以
  • AppDelegate中application:supportedInterfaceOrientationsForWindow:返回所有方向;
  • 除阅读器外的其它视图控制器,shouldAutorotate返回NO,supportedInterfaceOrientations返回竖屏;
  • 阅读器中shouldAutorotate返回YES;
  • 进入阅读器时,supportedInterfaceOrientations返回竖屏,如果需要横屏的话,在viewDidAppear中延时0.2秒调用旋转屏幕,并将supportedInterfaceOrientations中的返回值改为横屏;


代码示例:

 

1 AppDelegate.m
2 
3 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
4 return UIInterfaceOrientationMaskAll;
5 }

 

 

除阅读器外的视图控制器

 

 1 BaseViewController.m
 2 
 3 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
 4 return UIInterfaceOrientationMaskPortrait;
 5 }
 6 
 7 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
 8 return UIInterfaceOrientationPortrait;
 9 }
10 
11 - (BOOL)shouldAutorotate {
12 return NO;
13 }

 

 

阅读器

 

 1 BookReaderVC.m
 2 
 3 - (void)viewDidAppear:(BOOL)animated {
 4 [super viewDidAppear:animated];
 5 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 6 [self forceScreenDirectionToPortrait:YES];
 7 });
 8 }
 9 
10 - (void)forceScreenDirectionToPortrait:(BOOL)toPortrait {
11 if (toPortrait) {
12 self.orientation = UIInterfaceOrientationMaskPortrait;
13 [[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeRight) forKey:@"orientation"];
14 [[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
15 } else {
16 self.orientation = UIInterfaceOrientationMaskLandscapeRight;
17 [[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
18 [[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeRight) forKey:@"orientation"];
19 if (!IOS9_OR_LATER) {
20 UIViewController *blankVC = [[UIViewController alloc] init];
21 blankVC.view.backgroundColor = [UIColor clearColor];
22 [self presentViewController:blankVC animated:NO completion:nil];
23 [blankVC dismissViewControllerAnimated:NO completion:nil];
24 }
25 }
26 }
27 
28 - (BOOL)shouldAutorotate {
29 return YES;
30 }
31 
32 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
33 return self.orientation;
34 }

 

 

需要弹出键盘的视图控制器

 

1 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
2 UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
3 if (UIInterfaceOrientationIsLandscape(orientation)) {
4 return UIInterfaceOrientationMaskLandscapeRight;
5 } else {
6 return UIInterfaceOrientationMaskPortrait;
7 }
8 }

 

posted @ 2016-10-31 14:32  小Garfield  阅读(1894)  评论(0编辑  收藏  举报