iOS 屏幕旋转的实践解析——上篇

ZEGO即构科技
企业官方账号
2021-09-10 16:27:43

摘要:如何更灵活便捷的实现自定义屏幕旋转场景,本文带你揭秘!

图片

文|即构 iOS 应用开发团队

 

屏幕旋转是在视频直播类 APP 中常见的场景,在即构科技之前发布的 Roomkit SDK 中也有屏幕跟随手机自动旋转的场景。

在 Roomkit SDK 自身开发和客户接入的过程中我们也会发现,实现屏幕旋转的需求往往没有那么顺利,经常会出现无法旋转、旋转后布局适配等问题。

本篇文章根据我们以往的开发经验整理了屏幕旋转实现的相关实践方法,解析在实现过程中遇到的常见问题。

 

一、快速实现旋转

iOS 屏幕旋转的实现涉及到一堆枚举值和回调方法,对于没有做过旋转相关需求的开发来说,可能一上来就晕了,所以我们先动手,让屏幕转起来吧。

实现旋转的方式主要有两种,跟随手机感应旋转和手动旋转,接下来对这两种方式进行逐一介绍。

方式一:跟随手机感应器旋转

要实现自动跟随手机旋转,首先要让当前的视图控制器实现以下三个方法:

/// 是否自动旋转
- (BOOL)shouldAutorotate {
    return YES;
}

/// 当前 VC支持的屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}

/// 优先的屏幕方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

这种方法需要注意以下几点:

  • shouldAutorotate 返回 YES 表示跟随系统旋转,但是受 supportedInterfaceOrientations 方法的返回值影响,只支持跟随手机传感器旋转到支持的方向。

  • preferredInterfaceOrientationForPresentation 需要返回 supportedInterfaceOrientations中支持的方向,不然会发生 'UIApplicationInvalidInterfaceOrientation'崩溃。

 

方式二:手动旋转

这种方式在很多视频软件中都很常见,点击按钮后旋转至横屏。

这时需要在 shouldAutorotate 中返回 yes,然后再在此方法中 UIInterfaceOrientation 传入你需要旋转到的方向。注意这是私有方法,是否使用请自行斟酌。

- (void)changeVCToOrientation:(UIInterfaceOrientation)orientation {
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
        SEL selector = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        int val = orientation;
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}

 

场景应用

  • 自动旋转

如果你的 iPhone 没有关闭系统屏幕旋转,你就能发现系统相册 APP 的页面是可以跟着手机转动方向旋转的。

如果你想实现和它一样的效果,只需要按照前面方式一(跟随手机感应器旋转)去配置你的视图控制器的方法,之后控制器就可以在 supportedInterfaceOrientations 返回的方向内实现自由旋转了。

  • 只能手动旋转

这种场景比较少见,在视频直播类 APP 中常见的场景是自动和手动旋转相结合的方式。

如果你要实现只能通过像点击按钮去旋转的方式,首先需要在 supportedInterfaceOrientations 方法中返回你需要支持的方向,这里重点是shouldAutorotate 方法的返回值。

上面方式二中(手动旋转)说明了手动旋转需要 shouldAutorotate 返回 YES,但是这也会让控制器支持自动旋转,不符合这个需求,所以我们按以下方法处理:

- (BOOL)shouldAutorotate {
    if (self.isRotationNeeded) {
        return YES;
    } else {
        return NO;
    }
}    

 

属性 isRotationNeeded 作为是否需要旋转的标记,isRotationNeeded 默认为 NO,此时就算你旋转设备,回调 shouldAutorotate 方法时也不会返回 YES,所以屏幕也不会自动旋转。

剩下的只需要你在点击旋转的按钮后将 isRotationNeeded 置为 YES 并调用手动旋转的方法,这样处理后只能手动旋转的效果就实现了。

 

二、旋转后的 UI 布局更新

通常情况下,应用旋转到横竖屏后,因为不同的宽高比会有不同 UI,所以在屏幕旋转的场景中我们又需要解决旋转后 UI 适配的问题。

手机旋转时,正常情况下若 shouldAutorotate 返回 YES , 当视图控制器需要旋转就会触发 viewWillTransitionToSize 方法,这样我们就找到了去更新横竖屏 UI 的时机了,也就是在 completion block 里去完成旋转后的适配逻辑。

/*
This method is called when the view controller's view's size is
changed by its parent (i.e. for the root view controller when its window rotates or is resized).

If you override this method, you should either call super to
propagate the change to children or manually forward the 
change to children.
 */
- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        //横屏:size.width > size.height
        //竖屏: size.width < size.height
        NSLog(@"旋转完成,更新布局");
    
    }];
}

iOS 屏幕旋转的实践解析——下篇,请查看:https://bbs.csdn.net/topics/600565350

 

...全文
1609 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
0人已提交
完成率0%
暂无数据
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
CSDN-Ada助手 2023-01-13
  • 打赏
  • 举报
回复
您可以前往 CSDN问答-移动开发 发布问题, 以便更快地解决您的疑问

254

社区成员

发帖
与我相关
我的任务
社区描述
音视频技术干货的分享聚集!
音视频学习 企业社区
社区管理员
  • ZEGO即构
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

这里是音视频开发者小伙伴的聚集大本营!大家可在此集中讨论RTC开发相关内容、工作中遇到的问题、资源求助等。即构期待与大家共同打造一个开放、包容的RTC构建交流社区~

试试用AI创作助手写篇文章吧