iOS 设置随意屏幕旋转

方法一,通过控制器继承或分类实现:

在UITabBarController 的子类或分类中实现

 1 - (BOOL)shouldAutorotate {
 2     return [self.selectedViewController shouldAutorotate];
 3 }
 4 
 5 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
 6     return [self.selectedViewController supportedInterfaceOrientations];
 7 }
 8 
 9 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
10     return [self.selectedViewController preferredInterfaceOrientationForPresentation];
11 }

在UINavigationController 的子类或分类中实现

 1 - (BOOL)shouldAutorotate {
 2     return [self.topViewController shouldAutorotate];
 3 }
 4 
 5 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
 6     return [self.topViewController supportedInterfaceOrientations];
 7 }
 8 
 9 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
10     return [self.topViewController preferredInterfaceOrientationForPresentation];
11 }

在 UIViewController 的子类或分类中实现

 1 - (BOOL)shouldAutorotate {
 2     // 是否允许转屏
 3     return NO;
 4 }
 5 
 6 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
 7     // 所支持的全部旋转方向
 8     return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
 9 }
10 
11 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
12     // 初始显示的方向
13     return UIInterfaceOrientationPortrait;
14 }

最后在需要改变方向的控制器中重写以下方法实现可旋转功能

 1 - (BOOL)shouldAutorotate {
 2     // 是否允许转屏
 3     return YES;
 4 }
 5 
 6 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
 7     // 所支持的全部旋转方向
 8     return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
 9 }
10 
11 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
12     // 初始显示的方向
13     return UIInterfaceOrientationPortrait;
14 }

亲测可用

方法二:通过AppDelegate代理方法实现

 1 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
 2     
 3     if ([[self topViewController] isKindOfClass:[MyInterfaceController class]]) {
 4         return UIInterfaceOrientationMaskAllButUpsideDown;
 5     }
 6     return UIInterfaceOrientationMaskPortrait;//竖屏
 7 }
 8 
 9 // 获取当前window的顶层控制器
10 - (UIViewController *)topViewController {
11     UIViewController *resultVC;
12     resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
13     while (resultVC.presentedViewController) {
14         resultVC = [self _topViewController:resultVC.presentedViewController];
15     }
16     return resultVC;
17 }
18 
19 - (UIViewController *)_topViewController:(UIViewController *)vc {
20     if ([vc isKindOfClass:[UINavigationController class]]) {
21         return [self _topViewController:[(UINavigationController *)vc topViewController]];
22     } else if ([vc isKindOfClass:[UITabBarController class]]) {
23         return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
24     } else {
25         return vc;
26     }
27     return nil;
28 }

MyInterfaceController 为需要改变旋转方式的控制器

当从旋转过的屏幕返回不需要旋转的控制器时,需要强制旋转为指定方向,

- (void)viewWillAppear:(BOOL)animated 中调用:

 1 // 强制旋转屏幕
 2 - (void)interfaceOrientation:(UIInterfaceOrientation)orientation
 3 {
 4     SEL selector  = NSSelectorFromString(@"setOrientation:");
 5     if ([[UIDevice currentDevice] respondsToSelector:selector]) {
 6         // NSInvocation中保存了方法所属的对象/方法名称/参数/返回值
 7         // 其实NSInvocation就是将一个方法变成一个对象
 8         // 1.创建NSInvocation对象,设置方法签名
 9         NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
10         // 2.设置方法调用者
11         [invocation setTarget:[UIDevice currentDevice]];
12         // 3.写入签名方法
13         [invocation setSelector:selector];
14         // 4.设置参数
15         int val = orientation;
16         [invocation setArgument:&val atIndex:2]; // 设置索引2或更大(如果签名方法再有一个参数测设置3来进行索引传递); 0,1参数为target和selector
17         // 开始执行
18         [invocation invoke];
19     }
20 }

完毕 ,亲测可用

原文地址:https://www.cnblogs.com/MengXY/p/7218377.html