需求是这样的:
在控制器A中, 不允许转屏, 只能是竖屏
push到控制器B之后, 允许控制器自动转屏幕

实现方式

正常的实现逻辑中, 只需要在控制器A中实现以下

  1. – (BOOL)shouldAutorotate {
  2. return NO;
  3. }
  4. – (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  5. return UIInterfaceOrientationMaskPortrait;
  6. }

就可以实现了

但是今天遇到这么个问题, 无论怎么设置, 这些代码也执行, 但是都不起作用, 屏幕依然可以旋转.

问题

大概的查了一下, 跟UINavigationControllerUITabBarController相关的控制器, 会默认的走这两个基类的转屏方法, 自己写的这个就不会生效了, 检查appDelegate中发现如下代码:

  1. LCPlayerViewController *mainViewController = [[LCPlayerViewController alloc] initWithNibName:@”LCPlayerViewController”
  2. bundle:nil];
  3. UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
  4. navigationController.navigationBarHidden = YES;
  5. self.navigationController = navigationController;
  6. self.window.rootViewController = self.navigationController;
  7. [self.window makeKeyAndVisible];
  8. return YES;

解决方法

由于基本是UINavigationController, 所以跟上面说的那个一致, 自己实现的shouldAutorotate等方法不管用了, 于是解决办法如下:

  1. LECBaseNavigationController *navigationController = [[LECBaseNavigationController alloc] initWithRootViewController:mainViewController];

把创建的Nav变成了自己的一个Nav子类, 定义如下:

  1. #import “LECBaseNavigationController.h”
  2. @interface LECBaseNavigationController ()
  3. @end
  4. @implementation LECBaseNavigationController
  5. – (void)viewDidLoad {
  6. [super viewDidLoad];
  7. }
  8. – (BOOL)shouldAutorotate {
  9. return self.topViewController.shouldAutorotate;
  10. }
  11. – (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  12. return self.topViewController.supportedInterfaceOrientations;
  13. }
  14. – (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
  15. return self.topViewController.preferredInterfaceOrientationForPresentation;
  16. }
  17. @end

重写了三个跟转屏相关的方法, 把转屏的控制归还给实际的控制器, 再编译运行, 就可以实现自己的控制器控制自己转屏方向了.
代码在这

https://github.com/dfzr86/ScreenOrientationsDemo