热门标签 | HotTags
当前位置:  开发笔记 > IOS > 正文

总结iOSApp开发中控制屏幕旋转的几种方式

这篇文章主要介绍了iOSapp开发中控制屏幕旋转的方法总结,分为自动旋转和手动旋转以及强制旋转三种情况,代码为Objective-C语言,需要的朋友可以参考下

在iOS6之前的版本中,通常使用 shouldAutorotateToInterfaceOrientation 来单独控制某个UIViewController的方向,需要哪个viewController支持旋转,只需要重写shouldAutorotateToInterfaceOrientation方法。
但是iOS 6里屏幕旋转改变了很多,之前的 shouldAutorotateToInterfaceOrientation 被列为 DEPRECATED 方法,查看UIViewController.h文件也可以看到:

代码如下:

// Applications should use supportedInterfaceOrientations and/or shouldAutorotate.. 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation NS_DEPRECATED_IOS(2_0, 6_0); 

程序将使用如下2个方法来代替:
代码如下:

- (BOOL)shouldAutorotate; 
- (NSUInteger)supportedInterfaceOrientations; 

除了重写这个2个方法,IOS6之后要旋转还有一些需要注意的地方,下面会细述。另外还有一个硬性条件,需要在Info.plist文件里面添加程序支持的所有方向,可以通过以下2种方式添加
1.

201622991714779.png (493×56)

2.

201622991742247.png (492×242)

另外要兼容IOS6之前的系统,要保留原来的 shouldAutorotateToInterfaceOrientation 方法,还有那些 willRotateToInterfaceOrientation 等方法。

自动旋转设置:
控制某个viewController旋转并不是像IOS5或者IOS4一样在这个viewController里面重写上面那2个方法,而是需要在这个viewController的rootViewController(根视图控制器)里面重写,怎么解释呢?就是最前面的那个viewController,直接跟self.window接触的那个controller,比如以下代码:

代码如下:

UIViewController *viewCtrl = [[UIViewController alloc] init]; 
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:viewCtrl]; 
if ([window respondsToSelector:@selector(setRootViewController:)]) { 
    self.window.rootViewCOntroller= navCtrl; 
} else { 
    [self.window addSubview:navCtrl.view]; 


如果需要设置viewCtrl的旋转,那么不能在UIViewController里面重写shouldAutorotate和supportedInterfaceOrientations方法,而是需要在navCtrl里面设置,又因为UINavigationController是系统控件,所以这里需要新建一个UINavigationController的子navigationController的子类,然后在里面实现shouldAutorotate和supportedInterfaceOrientations方法,比如:
代码如下:

-(NSUInteger)supportedInterfaceOrientations{ 
    return UIInterfaceOrientationMaskAllButUpsideDown; 

 
- (BOOL)shouldAutorotate{ 
    return YES; 
}

eg1:如果上面的例子是self.window.rootViewCOntroller= viewCtrl,而不是navCtrl,那么上面的那2个控制旋转的方法就应该写在UIViewController里面!

eg2:如果viewCtrl又pushViewController到viewCtrl2,需要设置viewCtrl2的旋转,怎么办呢? 还是在navCtrl里面控制,因为viewCtrl和viewCtrl2的rootViewController都是navCtrl,一般的写法都是

代码如下:

UIViewController *viewCtrl2 = [[UIVewController alloc] init]; 
[self.navigationController.navigationController pushViewController:viewCtrl2 animated:YES];

所以要控制一个UINavigationController push到的所有viewController的旋转,那么就得在navCtrl里面区分是哪个viewController,以便对他们一一控制!同样如果rootViewController是UITabbarController,那么需要在子类化的UITabbarController里面重写那2个方法,然后分别控制!

但是有时候我初始化UINavigationController的时候,并不知道所有我所有需要push到的viewController,那么这里有一个通用的方法,就是让viewController自己来控制自己,首先在navCtrl里面的实现方法改为以下方式:

代码如下:

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


全部调用self.topViewController,就是返回当前呈现出来的viewController里面的设置,然后在viewCtrl、viewCtrl2等等这些viewController里面重写shouldAutorotate和supportedInterfaceOrientations,以方便设置每个viewController的旋转

eg3:如果viewCtrl 是 presentModalViewController 到 viewCtrl3,那么viewCtrl3的旋转设置就不在navCtrl里面了!如果presentModalViewController的viewController是navController、tabbarController包装过的viewCtrl3,那么就应在新包装的navController、tabbarController里面设置,如果是直接presentModalViewController到viewCtrl3,那么就在viewCtrl3里面设置


手动旋转
手动旋转也有2种方式,一种是直接设置 UIDevice 的 orientation,但是这种方式不推荐,上传appStore有被拒的风险:

代码如下:

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { 
    [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:(id)UIInterfaceOrientationPortrait]; 
}
 
第二种是假旋转,并没有改变 UIDevice 的 orientation,而是改变某个view的 transform,利用 CGAffineTransformMakeRotation 来达到目的,比如:
代码如下:

self.view.transform = CGAffineTransformMakeRotation(M_PI/2) 

下面讲解采用第二种方式的各版本手动旋转:
思想是首先设置 statusBarOrientation,然后再改变某个view的方向跟 statusBarOrientation 一致!

那既然是旋转,最少也得有2个方向,那么还是少不了上面说的那个硬性条件,先在plist里面设置好所有可能需要旋转的方向。既然是手动旋转,那么就要关闭自动旋转:

代码如下:

- (BOOL)shouldAutorotate{ 
        return NO; 
}
 
手动触发某个按钮,调用方法,这个方法的实现如下:
代码如下:

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; 
self.view.transform = CGAffineTransformMakeRotation(M_PI/2); 
self.view.bounds = CGRectMake(0, 0, kScreenHeight, 320);
 

注意:
1. 只需要改变self.view.transform,那么self.view的所有subview都会跟着自动变;其次因为方向变了,所以self.view的大小需要重新设置,不要使用self.view.frame,而是用bounds。
2. 如果shouldAutorotate 返回YES的话,下面设置setStatusBarOrientation 是不管用的!setStatusBarOrientation只有在shouldAutorotate 返回NO的情况下才管用!

强制旋转屏幕
最近接手了一个项目,正常情况下使用查看图片是没问题的。

用到了 MWPhotoBrowser 这个第三方图片浏览库。
不过发现了一个问题,就是设备横屏modal这MWPhotoBrowser的时候,发生了图片位置错乱。

实在没办法,所以想到了一个馊主意。

就是modal的时候使用代码把设备强制旋转回去。

代码如下:

//UIDevice+WJ.h
@interface UIDevice (WJ)
/**
 *  强制旋转设备
 *  @param  旋转方向
 */
+ (void)setOrientation:(UIInterfaceOrientation)orientation;
@end
//UIDevice+WJ.m
#import "UIDevice+WJ.h"
@implementation UIDevice (WJ)
//调用私有方法实现
+ (void)setOrientation:(UIInterfaceOrientation)orientation {
    SEL selector = NSSelectorFromString(@"setOrientation:");
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:[self currentDevice]];
    int val = orientation;
    [invocation setArgument:&val atIndex:2];
    [invocation invoke];
}
@end


推荐阅读
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 在 Windows 10 中,F1 至 F12 键默认设置为快捷功能键。本文将介绍几种有效方法来禁用这些快捷键,并恢复其标准功能键的作用。请注意,部分笔记本电脑的快捷键可能无法完全关闭。 ... [详细]
  • 本文将详细介绍如何使用剪映应用中的镜像功能,帮助用户轻松实现视频的镜像效果。通过简单的步骤,您可以快速掌握这一实用技巧。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 如何在PHPcms网站中添加广告
    本文详细介绍了在PHPcms网站后台添加广告的方法,涵盖多种常见的广告形式,如百度广告和Google广告,并提供了相关设置的步骤。同时,文章还探讨了优化网站流量的SEO策略。 ... [详细]
  • 当iOS设备越狱后,某些插件可能会导致系统崩溃(白苹果)。此时,可以通过进入安全模式来排查并删除有问题的插件。本文将详细介绍如何通过特定按键组合进入不加载MobileSubstrate的安全模式,并提供相关背景知识。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • C++: 实现基于类的四面体体积计算
    本文介绍如何使用C++编程语言,通过定义类和方法来计算由四个三维坐标点构成的四面体体积。文中详细解释了四面体体积的数学公式,并提供了两种不同的实现方式。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 如何优化2060显卡设置以提升《Apex英雄》游戏体验
    《Apex英雄》作为一款热门的战术竞技游戏,吸引了大量玩家。本文将探讨如何通过优化GeForce RTX 2060显卡设置,确保在《Apex英雄》中获得最佳性能和流畅的游戏体验。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文介绍如何通过SQL查询从JDE(JD Edwards)系统中提取所有字典数据,涵盖关键表的关联和字段选择。具体包括F0004和F0005系列表的数据提取方法。 ... [详细]
  • 如何高效创建和使用字体图标
    在Web和移动开发中,为什么选择字体图标?主要原因是其卓越的性能,可以显著减少HTTP请求并优化页面加载速度。本文详细介绍了从设计到应用的字体图标制作流程,并提供了专业建议。 ... [详细]
  • 本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ... [详细]
author-avatar
你虚伪的敷衍
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有