当前位置: 首页 > news >正文

iOS 中的界面旋转

级别: ★☆☆☆☆
标签:「iOS」「界面旋转 」「iOS 中的界面旋转」
作者: dac_1033
审校: QiShare团队


最近所接触的项目中有几处视频播放的需求,在该项目中视频播放器可以全屏/竖屏手动切换,也可以自动切换,但是其他界面都是竖屏状态来展示。因此,总结了一下iOS中关于界面旋转,即横屏/竖屏切换相关的一些知识点。

注意:在iOS中没有显式的设置界面方向的方法。

1. 视图view的旋转

如果需求是只对一个view进行旋转,我们可以直接调用以下方法,对视图进行手动旋转。

view.transform = CGAffineTransformMakeRotation(M_PI_2);
复制代码

如果你想用此方式实现把app当前的整个界面都旋转成横屏,你可能还需要以下方法:

// 状态栏也要旋转
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];

// 强制设置设备方向,以设置键盘弹出方向(注:但这是个私有方法)
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:@"orientation"];
复制代码

2. 用系统方法实现界面旋转

用系统方法实现的是界面的自动旋转,首先,需要在工程中勾选一下选项:

其次,在AppDelegate中实现以下方法:

// 整个app允许的自动旋转的方向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
   
    return UIInterfaceOrientationMaskPortrait;
}
复制代码

最后,在相应的ViewController中实现一下系统方法:

// 是否能够旋转
- (BOOL)shouldAutorotate;

// 支持的旋转方向
-(UIInterfaceOrientationMask)supportedInterfaceOrientations;

// 模态视图初始化时的旋转方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
复制代码

屏幕旋转是从全屏视图的方法来判定的,即root视图来判定的。也就是说每次判定页面是否需要旋转都是从图中最左侧的nav判定。我们要做到每个页面自定义的话需要在UINavigationController和UITabbarController中分别实现如下方法:

 在NavgationController的基类中粘贴以下代码
- (BOOL)shouldAutorotate {

    return self.topViewController.shouldAutorotate;
}
 
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {

    return self.topViewController.supportedInterfaceOrientations;
}
 
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

    return [self.topViewController preferredInterfaceOrientationForPresentation];
}


  在TabbarController的基类中粘贴以下代码
- (BOOL)shouldAutorotate {

    return self.selectedViewController.shouldAutorotate;
}
 
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {

    return self.selectedViewController.supportedInterfaceOrientations;
}
 
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

    return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}
复制代码

3. 获取、监听设备的方向

  • 获取设备方向
// 获取设备方向
[[UIApplication sharedApplication] statusBarOrientation];
[[UIDevice currentDevice] orientation];
复制代码
  • 添加监听设备旋转的通知
// 添加监听设备旋转的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil];

- (void)deviceOrientationChange:(NSNotification *)notification {
    
    UIDeviceOrientation  orient = [UIDevice currentDevice].orientation;
    
    switch (orient) {
        case UIDeviceOrientationPortrait:
            
            break;
        case UIDeviceOrientationLandscapeLeft:
            
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            
            break;
        case UIDeviceOrientationLandscapeRight:
            
            break;
            
        default:
            break;
    }
}


// 添加监听界面旋转的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

- (void)statusBarOrientationChange:(NSNotification *)notification {
    
     UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    
    if (orientation == UIInterfaceOrientationLandscapeRight) {
        
    }
    
    if (orientation ==UIInterfaceOrientationLandscapeLeft) {

    }
    
     if (orientation == UIInterfaceOrientationPortrait){
         
     }
    
    if (orientation == UIInterfaceOrientationPortraitUpsideDown){

    }
}
复制代码

4. 界面旋转的应用实例

如开头所说,如果app中有QiTabBarController、UINavigationController、UIViewController等多层次的界面情况下,我们只想让某个界面自动旋转功能,怎么实现呢?
(1)基类UITabBarController 、QiNavigationController中实现上面?的代码;
(2)基类QiViewController中的shouldAutorotate方法返回NO;
(3)继承于QiViewController的子controller中的shouldAutorotate方法返回YES,即可实现上述功能。

5. 强制某个界面旋转

在iOS3以前可以通过UIDevice的setOrientation来实现,但之后变成了私有方法,不能直接调用。我们利用 KVO机制去间接调用,是否能够提交并成功发布至AppStore就靠运气了!

 最直接的
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];


 含蓄的
- (void)forceOrientation {

    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 = UIInterfaceOrientationLandscapeLeft;//横屏
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}
复制代码

工程源码GitHub地址


小编微信:可加并拉入《QiShare技术交流群》。

关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
iOS 常用布局方式之Frame
iOS 常用布局方式之Autoresizing
iOS 常用布局方式之Constraint
iOS 常用布局方式之StackView
iOS 常用布局方式之Masonry
iOS UIButton根据内容自动布局
iOS 指定初始化方法
UIView中的hitTest方法
奇舞周刊

转载于:https://juejin.im/post/5d0233da6fb9a07eac05ce51

相关文章:

  • Django具体操作(三)
  • 超简单配置Android持续集成自动化打包流程 - GitHub+GitLab-CI+蒲公英+钉钉
  • 51NOD 1565:模糊搜索——题解
  • STL priority实例
  • Severless SQL on OSS 实验(DataLakeAnalytics on OSS)
  • MYSQL下对远程用户进行连接授权
  • php中mysqli 处理查询结果集的几个方法
  • python常用模块
  • windows mysql 8
  • 云计算大数据,知识体系
  • 瓜脸识别神器让标签看得见,看ET农业大脑是如何将生鲜品牌化?
  • Jenkins+pipeline+参数构建+人工干预确定
  • sql -- 移除数据中的换行符和回车符
  • 总结http get和post的区别
  • SpringBoot案例中关于添加的方式
  • [case10]使用RSQL实现端到端的动态查询
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 07.Android之多媒体问题
  • Android框架之Volley
  • Apache Spark Streaming 使用实例
  • Apache的80端口被占用以及访问时报错403
  • Fundebug计费标准解释:事件数是如何定义的?
  • Java-详解HashMap
  • Linux快速复制或删除大量小文件
  • ng6--错误信息小结(持续更新)
  • Python学习之路13-记分
  • SpiderData 2019年2月16日 DApp数据排行榜
  • SpingCloudBus整合RabbitMQ
  • Vue.js 移动端适配之 vw 解决方案
  • Vue.js-Day01
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • WebSocket使用
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 多线程 start 和 run 方法到底有什么区别?
  • 工作手记之html2canvas使用概述
  • 简单数学运算程序(不定期更新)
  • 力扣(LeetCode)357
  • 区块链将重新定义世界
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 算法---两个栈实现一个队列
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • elasticsearch-head插件安装
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​什么是bug?bug的源头在哪里?
  • (ZT)薛涌:谈贫说富
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .Net 知识杂记
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • @DataRedisTest测试redis从未如此丝滑
  • @ResponseBody