iOS-屏幕旋转控制总结

这段时间做的一个app,需求是大部分界面竖屏,播放器页面横屏,网页播放可横屏可竖屏。查阅了一些资料,也踩了一些坑, 在这里做一个总结。

iOS如何支持旋屏

1. project->target->Deployment Info->Device Orientation


这里的Landscape LeftDevice Orientation,是指内容的方向,即此时手机向右旋转,home键在左边;而Landscape Right表示手机向右左旋转,home键在右边

2. 代码控制

在AppDelegate中添加方法

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskAll;
}

当使用代码控制旋屏方向时,第一点的Device Orientation配置就失效了

关于旋屏之后状态栏消失的问题,解决办法是在需要旋屏的UIViewController中重写3个方法

//设置样式
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

//设置是否隐藏
- (BOOL)prefersStatusBarHidden {
    return NO;
}

//设置隐藏动画
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationNone;
}

如果不想在ViewController中都去重写,可以选择

  1. 继承一个基类ViewController,在基类中重写上述3个方法
  2. 新建Category
@implementation UIViewController (StatusBarCategory)

//设置样式
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

//设置是否隐藏
- (BOOL)prefersStatusBarHidden {
    return NO;
}

//设置隐藏动画
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationNone;
}

@end

如果风格统一,推荐第二种写法,尽量减少使用继承;若需要定制状态栏,可以使用第一种方案

那么现在来说说需要解决旋屏的需求

通常app大部分界面竖屏,有的界面强制横屏,如播放器,而有的界面支持横竖屏,如UIWebView

因为所有的旋屏都会走AppDelegate的方法

-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;

所以在AppDelegate.h暴露2个参数

@property (nonatomic, assign) BOOL allowRotate;
@property (nonatomic, assign) UIInterfaceOrientationMask interfaceOrientation;

AppDelegate.m中

//初始化参数
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.allowRotate = NO;
    self.interfaceOrientation = UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return self.allowRotate?self.interfaceOrientation:UIInterfaceOrientationMaskPortrait;
}

在需要旋屏的ViewController中

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    ((AppDelegate *)[UIApplication sharedApplication].delegate).allowRotate = YES;
    //需要旋屏支持的方向
    ((AppDelegate *)[UIApplication sharedApplication].delegate).interfaceOrientation = UIInterfaceOrientationMaskLandscapeRight;
    //强制旋屏
    [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    ((AppDelegate *)[UIApplication sharedApplication].delegate).allowRotate = NO;
    //还原竖屏
    ((AppDelegate *)[UIApplication sharedApplication].delegate).interfaceOrientation = UIInterfaceOrientationMaskPortrait;
    //强制旋屏,还原竖屏
    [[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

其中比较重要的一行

 [UIViewController attemptRotationToDeviceOrientation];

当你发生屏幕旋转时调用这句代码,可以解决一些奇怪的bug,比如横屏返回后,本应竖屏的界面也是横屏等。

结语

在测试当中,碰到一些问题:

  • 旋屏后的手势返回问题,这个问题可以通过禁用返回手势解决
  • 依然会有push后不横屏的情况,但是概率不高,在能接受的范围,具体原因不详,若有解决方案的朋友欢迎来交流。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • iOS屏幕旋转学习笔记iOS开发中使用屏幕旋转功能的相关方法 1、基本知识点解读 了解屏幕旋转首先需要区分两种 o...
    Laughingg阅读 14,605评论 13 39
  • 前段时间抽空总结了一下iOS视频播放的基本用法,发现这其中还有一个我们无法绕过的问题,那就是播放界面的旋转与适配。...
    梧雨北辰阅读 31,578评论 14 147
  • [这是第11篇] 导语: iOS App中大多数页面是只展示竖屏下的效果,但是少部分页面需要支持横竖屏。本文分别介...
    南华coder阅读 14,877评论 18 93
  • 1、UIDeviceOrientation 设备的物理方向 简介UIDeviceOrientation即我们手持的...
    MrJ的杂货铺阅读 27,953评论 8 75
  • 1. 昨天晚上打车,遇到一个滴滴司机,就跟他聊天,他说已经在北京有两套房子,三个孩子,两个已经大学毕业,最小的儿子...
    刘灰灰阅读 2,047评论 0 0