VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo

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 methodsupported 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所验证的结论是: 你app在屏幕上正在展示的所有VC所处的旋转方向(默认是竖屏方向)取决于(AppDelegate的application:supportedInterfaceOrientationsForWindow:方法返回的‘方向集合’)∩(“根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.句子中the root view controller or topmost presented view controller应该被当成一个整体来理解,里面的or表示的是并集的意思!

The app and view controller must agree before the rotation is allowed.意思是只有VC的shouldAutorotate方法返回YES时,VC界面才可能会随着手机屏幕的旋转而旋转!
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第1张图片

步骤2,如果上述不想看,直接看下图的结论:
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第2张图片

设置app工程所支持的旋转方向,该设置会使整个全局生效。并且,如果在下图的设置里面只支持A方向,那么工程代码里面的VC就不能旋转到B方向。所以下图的方向基本上都是全部打钩。

VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第3张图片

本文代码都是基于genel里面设置了支持全部屏幕方向(如下图)为背景实现的

VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第4张图片

场景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的界面是横屏的(具体是向右横屏)

VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第5张图片

场景2:NavigationController+VC

demo1,一个NavigationController+1个VC

如下图所示,Window的rootVC是MyNavigationController,而MyNavigationController的rootVC是ViewController。
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第6张图片
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界面并不会跟着手机的旋转而旋转。
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第7张图片

VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第8张图片

场景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界面)都会跟着手机的旋转而旋转。
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第9张图片

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都不会旋转了。。
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第10张图片

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界面都不会随着手机的旋转
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第11张图片

场景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界面并不会随着手机屏幕的旋转而旋转
VC的shouldAutorotate和supportedInterfaceOrientations方法的学习demo_第12张图片

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界面都会随着屏幕的旋转而旋转。

你可能感兴趣的:(ios)