概述
ios屏幕旋转:当全屏模式(此时是横屏模式)时,把app退后台然后再进入app时,横屏模式变成竟然变成了竖屏模式的解决方法。
步骤1:先看下图苹果文档的discussion部分。但这句话应该这样读:
①This method returns the total set of interface orientations supported by the app.
意思是该方法返回的是app所支持的界面旋转方向集合。
②对于When determining whether to rotate a particular view controller, the orientations returned by this method are intersected with the orientations supported by the root view controller or topmost presented view controller.
,这句话先看When determining whether to rotate a particular view controller,
,意思是某个VC界面的方向取决于。 接着看the orientations returned by this method are intersected with the orientations supported by the root view controller or topmost presented view controller.
,这句话比较长,在读英语句子的时候,如果句子比较长,可以先找出句子的主干,因为句子的主干就代表了这句话的意思,那怎么找出这句话的主干呢?答案是,第一步,先找出动词,因为这句话是一般时态,所以很明显are就是动词,因为一个英语句子里面只能有一个动词,所以returned和supported都是被动语态,被动语态可以当做定语,所以returned和supported都是定语,所以进入第二步,去掉定语,returned by this method
表示该方法的返回值,supported by the root view controller or topmost presented view controller
表示根VC或者最顶层的被present的VC,去掉returned by this method
和supported by the root view controller or topmost presented view controller
这两个定语;第三步,看主干,此时句子的主干就是the orientations are intersected with the orientations
,翻译成中文的意思就是 ’方向集合‘和’方向集合‘的交集,前一个’方向集合’由returned by this method
定语修饰,所以前一个‘方向集合’指的是application:supportedInterfaceOrientationsForWindow:
方法返回的‘方向集合’,而后一个‘方向集合’被supported by the root view controller or topmost presented view controller
这个定语修饰,所以后一个‘方向集合’就是 “根VC” 或者 “被present的顶部VC”的supportedInterfaceOrientations()方法返回的‘方向集合’。综上,When determining whether to rotate a particular view controller, the orientations returned by this method are intersected with the orientations supported by the root view controller or topmost presented view controller.
意思就是一个VC界面最终所支持的旋转方向取决于:AppDelegate的application:supportedInterfaceOrientationsForWindow:方法返回的‘方向集合’和 【“根VC” 或者 “被present的顶部VC”的supportedInterfaceOrientations()方法返回的‘方向集合’】的交集。但在实际demo所验证的结论是: 第①种情况,当前屏幕的topmostVC是被present出来的,并且topmostVC的modalPresentationStyle是UIModalPresentationOverFullScreen或者UIModalPresentationFullScreen,即topmostVC占据了整个屏幕(能占据整个屏幕的topmostVC指的是present目标VC前,你给目标VC的modalPresentationStyle
属性设置了UIModalPresentationOverFullScreen或者UIModalPresentationFullScreen
。),此时你app在屏幕上正在展示的所有VC所处的旋转方向(默认是竖屏方向)取决于(AppDelegate的application:supportedInterfaceOrientationsForWindow:方法返回的‘方向集合’)∩(topmostVC的supportedInterfaceOrientations方法返回的‘方向集合’);第②种情况,当前屏幕的topmostVC不是被present出来的,或者topmostVC是被present出来但其没有占据整个屏幕(即topmostVC的modalPresentationStyle既是UIModalPresentationOverFullScreen也不是UIModalPresentationFullScreen),此时你app在屏幕上正在展示的所有VC所处的旋转方向(默认是竖屏方向)取决于(AppDelegate的application:supportedInterfaceOrientationsForWindow:方法返回的‘方向集合’)∩(rootVC的supportedInterfaceOrientations方法返回的‘方向集合’)。建议:既然the orientations returned by this method are intersected with the orientations supported by the root view controller or topmost presented view controller
,那么你就重写rootVC的topVC里面的supportedInterfaceOrientations()方法,重写成if (self.presentedViewController && !self.presentedViewController.isBeingPresented && !self.presentedViewController.isBeingDismissed && [self.presentedViewController isKindOfClass:FullscreenViewController.class]) { return self.presentedViewController.supportedInterfaceOrientations; } return [super supportedInterfaceOrientations];
③The app and view controller must agree before the rotation is allowed.
意思是只有VC的shouldAutorotate方法返回YES时,VC界面才可能会随着手机屏幕的旋转而旋转!
步骤2,如果上述不想看,直接看下面的结论:
界面支持的屏幕旋转方向 = “AppDelegate的application:supportedInterfaceOrientationsForWindow:方法返回的‘方向集合’” 和 "fun()方法返回的‘方向集合’"的交集。其中,fun()方法的实现如下:
- (UIInterfaceOrientation)fun {
if (topmostVC是被present出来的) {
if (topmostVC是占据了整个屏幕) {
if ([topmostVC shouldAutorotate]) {
return [topmostVC supportedInterfaceOrientations];
} else {
return 界面不随手机的旋转而旋转
}
} else {
return [rootVC supportedInterfaceOrientations]; //rootVC就是你app的UIWindow的rootViewController
}
}
}
设置app工程所支持的旋转方向,该设置会使整个全局生效。并且,如果在下图的设置里面只支持A方向,那么工程代码里面的VC就不能旋转到B方向。所以下图的方向基本上都是全部打钩。
本文代码都是基于genel里面设置了支持全部屏幕方向(如下图)为背景实现的
场景1:app只有一个VC
demo1
代码如下所示
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
ViewController *vc = [ViewController new];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
return YES;
}
@end
如下图,在ViewController中重写shouldAutorotate()和supportedInterfaceOrientations()方法
结论:从上图的打印结果可以看出,shouldAutorotate()默认返回yes,即默认支持 跟随重力旋转手机而自动旋转VC的界面。supportedInterfaceOrientations()返回30,30对应的enum值是UIInterfaceOrientationMaskAll,即支持所有方向的旋转。不信你就旋转你的手机试试。。
demo2
在demo1的基础上,保持AppDelegate代码不变,修改ViewController的代码,代码如下
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(100, 10, 100, 100)];
self.button.backgroundColor = UIColor.blueColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.view addSubview:self.button];
}
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeRight; //该VC支持右横屏
}
@end
结果如下图,ViewController和Window都处于横屏,此时你的手机无论怎么旋转,ViewController的界面都是不会跟着旋转的。因为ViewController的supportedInterfaceOrientations()返回的是UIInterfaceOrientationMaskLandscapeRight,即VC只支持右横屏。
demo3, shouldAutorotate()返回NO
修改ViewController的代码,代码如下
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(100, 10, 100, 100)];
self.button.backgroundColor = UIColor.blueColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.view addSubview:self.button];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"即使shouldAutorotate()返回的是NO,这个方法也会被调用.只不过该VC的界面不会跟着手机的旋转而发生旋转,因为shouldAutorotate()返回的是NO");
return [super supportedInterfaceOrientations];
}
@end
运行结果如下图。因为shouldAutorotate()返回NO,所以该VC的界面不会跟着手机的旋转而发生旋转。但是手机旋转到新的方向后(比如从竖屏旋转到横屏),shouldAutorotate()和supportedInterfaceOrientations()都会被调用,只不过因为shouldAutorotate()返回的是NO,所以supportedInterfaceOrientations()即使返回UIInterfaceOrientationMaskAll也不会导致界面随着手机的旋转而旋转。
demo4, shouldAutorotate()返回NO,supportedInterfaceOrientations()返回UIInterfaceOrientationMaskLandscapeRight
修改ViewController的代码,代码如下
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(100, 10, 100, 100)];
self.button.backgroundColor = UIColor.blueColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.view addSubview:self.button];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"即使shouldAutorotate()返回的是NO,这个方法也会被调用.只不过该VC的界面不会跟着手机的旋转而发生旋转,因为shouldAutorotate()返回的是NO");
return UIInterfaceOrientationMaskLandscapeRight;
}
@end
运行结果如下图。因为shouldAutorotate()返回NO,所以该VC的界面不会跟着手机的旋转而发生旋转。但是手机旋转到新的方向后(比如从竖屏旋转到横屏),shouldAutorotate()和supportedInterfaceOrientations()都会被调用,只不过因为shouldAutorotate()返回的是NO,所以supportedInterfaceOrientations()即使返回UIInterfaceOrientationMaskLandscapeRight也不会导致界面随着手机的旋转而旋转。注意的是,VC的界面是横屏的(具体是向右横屏)
场景2:NavigationController+VC
demo1,一个NavigationController+1个VC
如下图所示,Window的rootVC是MyNavigationController,而MyNavigationController的rootVC是ViewController。
MyNavigationController的核心代码如下
@implementation MyNavigationController
- (BOOL)shouldAutorotate {
BOOL flag = [super shouldAutorotate];
NSLog(@"%s, shouldAutorotate=%d", __func__, flag);
return flag;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
UIInterfaceOrientationMask orientations = [super supportedInterfaceOrientations];
NSLog(@"%s, orientations=%llu", __func__, orientations);
return orientations;
}
@end
AppDelegate的核心代码如下
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = UIColor.blueColor;
ViewController *vc = [ViewController new];
MyNavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nvc;
[self.window makeKeyAndVisible];
return YES;
}
@end
ViewController的核心代码如下
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(100, 10, 100, 100)];
self.button.backgroundColor = UIColor.redColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.view addSubview:self.button];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"即使shouldAutorotate()返回的是NO,这个方法也会被调用.");
return UIInterfaceOrientationMaskLandscapeRight;
}
@end
运行结果如下图.此时你旋转屏幕,VC界面也会随着手机的旋转而旋转,说明VC的shouldAutorotate()失效,而真正起作用的是MyNavigationController的shouldAutorotate()。NavigationController的shouldAutorotate()默认也返回yes,即默认支持 跟随重力旋转手机而自动旋转VC的界面,supportedInterfaceOrientations()默认也返回30,30对应的enum值是UIInterfaceOrientationMaskAll,即支持所有方向的旋转。
demo2
此时在MyNavigationController的shouldAutorotate()返回NO,而在ViewController的shouldAutorotate()返回YES,代码如下
MyNavigationController代码
@implementation MyNavigationController
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;//本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
UIInterfaceOrientationMask orientations = [super supportedInterfaceOrientations];
NSLog(@"%s, orientations=%llu", __func__, orientations);
return orientations;
}
@end
ViewController代码如下
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(100, 10, 100, 100)];
self.button.backgroundColor = UIColor.redColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.view addSubview:self.button];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return YES; //本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"即使shouldAutorotate()返回的是NO,这个方法也会被调用.");
return UIInterfaceOrientationMaskLandscapeRight;
}
运行结果如下,此时旋转手机发现,VC界面并不会跟着手机的旋转而旋转,所以VC的shouldAutorotate()失效,而真正起作用的是MyNavigationController的shouldAutorotate()。
demo3
我们希望每一个界面所支持的方向都由当前VC来控制,因为这样灵活性比较高,所以我们只需在NavigationController的shouldAutorotate()和supportedInterfaceOrientations()方法中返回栈顶VC的相应方法即可完成我们的目标。代码如下
MyNavigationController的代码如下
@implementation MyNavigationController
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return self.topViewController.shouldAutorotate; //本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return self.topViewController.supportedInterfaceOrientations; //本次修改
}
@end
运行结果如下,此时旋转手机发现,VC界面并不会跟着手机的旋转而旋转,因为MyNavigationController的shouldAutorotate()和supportedInterfaceOrientations()都由其栈顶的VC(本例为ViewController)的相应方法决定,又因为VC的supportedInterfaceOrientations()返回UIInterfaceOrientationMaskLandscapeRight,即只支持向右横屏,此时无论VC的shouldAutorotate()是否返回YES(这种情况下返回NO的结果也相同),旋转手机会发现,VC界面并不会跟着手机的旋转而旋转。
demo4
AppDelegate代码如下
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = UIColor.blueColor;
ViewController *vc = [ViewController new];
MyNavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nvc;
[self.window makeKeyAndVisible];
return YES;
}
@end
MyNavigationController代码如下
@implementation MyNavigationController
- (BOOL)shouldAutorotate {
NSString *a = nil;
NSString *b = nil;
NSString *c = @"";
NSLog(@"%d, %d", [a isEqualToString:b], [c isEqualToString:b]);
NSLog(@"%s", __func__);
return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return self.topViewController.supportedInterfaceOrientations;
}
@end
ViewController代码如下
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(100, 10, 100, 100)];
self.button.backgroundColor = UIColor.redColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.view addSubview:self.button];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;//本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return [super supportedInterfaceOrientations];//本次修改
}
@end
运行结果如下两张图,如果app打开时手机处于竖屏状态,那么VC界面就是竖屏状态(下面第1张图),而如果app打开时手机处于横屏状态,那么VC界面就是横屏状态(下面第2张图).因为VC的shouldAutorotate()返回为NO,所以此时旋转手机发现,VC界面并不会跟着手机的旋转而旋转。
场景3:NavigationController+VC + AlertVC
demo1
AppDelegate代码如下
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = UIColor.blueColor;
ViewController *vc = [ViewController new];
MyNavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nvc;
[self.window makeKeyAndVisible];
return YES;
}
@end
MyNavigationController代码如下
@implementation MyNavigationController
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return self.topViewController.supportedInterfaceOrientations;
}
@end
ViewController代码如下
#import "MyAlertVC.h"
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(10, 100, 100, 100)];
self.button.backgroundColor = UIColor.redColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.button addTarget:self action:@selector(presentClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.button];
}
- (void)presentClick {
MyAlertVC *actionSheetController = [MyAlertVC alertControllerWithTitle:@"手机空间不足" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cealrVideoAction = [UIAlertAction actionWithTitle:@"清理离线下载视频" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction *clearPhoneAction = [UIAlertAction actionWithTitle:@"清理手机空间" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if (@available(iOS 10, *)) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
#pragma clang diagnostic pop
}else {
[[UIApplication sharedApplication] openURL:url];
}
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"3333" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[actionSheetController addAction:cealrVideoAction];
[actionSheetController addAction:clearPhoneAction];
[actionSheetController addAction:cancelAction];
[self presentViewController:actionSheetController animated:YES completion:nil];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return [super supportedInterfaceOrientations];
}
@end
MyAlertVC代码如下
@implementation MyAlertVC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate {
BOOL flag = [super shouldAutorotate];
NSLog(@"%s, autorotate=%d", __func__, flag);
return flag;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
UIInterfaceOrientationMask orientations = [super supportedInterfaceOrientations];
NSLog(@"%s,orientations=%llu", __func__, orientations);
return orientations;
}
@end
运行结果如下图
点击红色按钮,结果如下图。从orientation=30的结果可以知道UIAlertController默认和其父类UIViewController一样支持各个方向的旋转。所以此时旋转手机发现,所有VC界面(比如VC界面和AlertVC界面)都会跟着手机的旋转而旋转。

demo2
修改MyAlertVC,shouldAutorotate()返回YES,supportedInterfaceOrientations()返回UIInterfaceOrientationMaskLandscapeRight。代码如下
@implementation MyAlertVC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__); //本次修改
return YES; //本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);//本次修改
return UIInterfaceOrientationMaskLandscapeRight;//本次修改
}
@end
运行结果如下图:当点击红色按钮弹出AlertVC时,AlertVC并没有按横屏弹出。。并且此时系统只调用了supportedInterfaceOrientations()而没有调用shouldAutorotate()。此时旋转手机屏幕时,如果旋转到非UIInterfaceOrientationMaskLandscapeRight,那么所有VC界面都不会随着旋转,而如果旋转到UIInterfaceOrientationMaskLandscapeRight方向时,所有VC界面都会随着旋转到UIInterfaceOrientationMaskLandscapeRight方向,之后无论手机怎么旋转,所有界面VC都不会旋转了。。
demo3
MyAlertVC的shouldAutorotate()返回NO
@implementation MyAlertVC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO; //本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return UIInterfaceOrientationMaskLandscapeRight;
}
@end
运行结果如下图,当点击红色按钮弹出AlertVC时,AlertVC并没有按横屏弹出。。并且此时系统只调用了supportedInterfaceOrientations()而没有调用shouldAutorotate()。此时旋转手机屏幕时,AlertVC的shouldAutorotate()会被调用,因为返回值为NO,所以所有VC界面都不会随着手机的旋转
场景4:UITabBarController+NavigationController+VC
demo1
AppDelegate代码如下
#import "AppDelegate.h"
#import "ViewController.h"
#import "MyNavigationController.h"
#import "MyTabBarVC.h"
#import "EmptyVC.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = UIColor.blueColor;
ViewController *vc = [ViewController new];
MyNavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:vc];
MyTabBarVC *tabVC = [[MyTabBarVC alloc] init];
nvc.tabBarItem.title = @"测试VC";
[tabVC addChildViewController:nvc];
//不需要管emptyVC,只是让你知道有个tabVC就ok
EmptyVC *emptyVC = [EmptyVC new];
emptyVC.tabBarItem.title = @"你不用管";
[tabVC addChildViewController:emptyVC];
self.window.rootViewController = tabVC;
[self.window makeKeyAndVisible];
return YES;
}
@end
MyNavigationController代码如下
@interface MyNavigationController ()
@end
@implementation MyNavigationController
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return self.topViewController.supportedInterfaceOrientations;
}
@end
ViewController代码如下
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIButton *button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.button = [[UIButton alloc] initWithFrame:CGRectMake(10, 100, 100, 100)];
self.button.backgroundColor = UIColor.redColor;
[self.button setTitle:@"按钮" forState:UIControlStateNormal];
[self.button addTarget:self action:@selector(presentClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.button];
}
- (void)presentClick {
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__);
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__);
return [super supportedInterfaceOrientations];
}
@end
运行结果如下图。从打印结果可以看出,UITabBarController默认支持自动旋转,并且支持各个方向的旋转(因为orientations==30,30对应UIInterfaceOrientationMaskAll)。此时所有VC界面都会随着手机屏幕的旋转而旋转。
demo2
在demo1的基础上,只修改MyTabBarVC的shouldAutorotate()返回值
@implementation MyTabBarVC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s", __func__); //本次修改
return NO; //本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s", __func__); //本次修改
return [super supportedInterfaceOrientations];
}
@end
打印结果如下,此时旋转手机屏幕,所有VC界面并不会随着手机屏幕的旋转而旋转
demo3
在demo1的基础上,修改MyTabBarVC的shouldAutorotate()和supportedInterfaceOrientations()的返回值为selectedViewController的相应方法的返回值。
@implementation MyTabBarVC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate {
NSLog(@"%s,self.selectedViewController=%@", __func__, self.selectedViewController);
return self.selectedViewController.shouldAutorotate; //本次修改
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
NSLog(@"%s,self.selectedViewController=%@", __func__, self.selectedViewController);
return self.selectedViewController.supportedInterfaceOrientations;//本次修改
}
@end
运行结果如下图,此时旋转手机屏幕,会发现所有的VC界面都不会随着屏幕的旋转而旋转,因为ViewController的shouldAutorotate()返回NO。如果此时你把ViewController的shouldAutorotate()返回值设为YES,那么旋转手机屏幕,会发现所有的VC界面都会随着屏幕的旋转而旋转。
shouldAutorotate
当界面不存在被present的VC时,你的界面是否支持自动旋转是由UIWindow的rootViewController(下文简称rootVC)的shouldAutorotate()的返回值决定的。
当界面的topmost是被present的VC时,你的界面是否支持自动旋转是由下面的fun()函数决定的。
- (BOOL)fun {
if (topmostVC是全屏展示) { //即topmostVC.modalPresentationStyle的值为UIModalPresentationFullScreen或者UIModalPresentationOverFullScreen
if (![topmostVC shouldAutorotate]) {
return NO;
} else {
if (topmostVC.modalPresentationStyle == UIModalPresentationFullScreen) {
return YES;
} else { //能执行下一行代码说明topmostVC.modalPresentationStyle == UIModalPresentationOverFullScreen
return [rootVC shouldAutorotate];
}
}
} else {
return [rootVC shouldAutorotate];
}
}
最后
以上就是自然项链为你收集整理的VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demoshouldAutorotate的全部内容,希望文章能够帮你解决VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demoshouldAutorotate所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复