相信很多APP大多数页面都是竖屏,而只有部分页面会旋转,播放器是其代表之一。
但是工程的Landscape Left 和Landscape Right去掉,则部分页面也不支持旋转,Landscape Left 和Landscape Right开启又导致默认是的转屏,所以我们需要自己来实现逻辑控制界面是否可转并且还要默认是竖屏
废话也不多说,我来说说我的解决方案。
在设置的过程中首先提几点要求:
1、默认的所有页面是竖屏的
2、部分页面可以通过设置开关支持旋转。
解决思路:
1、首先我们先想到的是将plist的Landscape Left 和Landscape Right关掉,但是关掉了工程的配置,在单个页面开启旋转是行不通的。
2、那我们就不靠工程的配置,自己写逻辑来控制,在iOS6之后AppDelegate里面有个
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window
该方法在每次屏幕旋转的时候可以设置页面是否转屏。
新建个工具类AutoRotate.h具体代码逻辑如下
+ (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
if (window != nil) {
UIWindow *w = [UIApplication sharedApplication].delegate.window;
return [self orientationFromWindow:w];
}
return UIInterfaceOrientationMaskPortrait;
}
+ (UIInterfaceOrientationMask)orientationFromWindow:(UIWindow *)window {
UIViewController *rootViewController = window.rootViewController;
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabar = (UITabBarController *)rootViewController;
//获取当前选择的navigationController
UINavigationController *nav = tabar.selectedViewController;
//获取当前显示的viewController
UIViewController *topViewController = nav.topViewController;
//获取当前界面的presentedViewController
UIViewController *presentedViewController = topViewController.presentedViewController;
//正在显示的viewController
UIViewController *showViewController = topViewController;
//如果有presentedViewController,则用
if (presentedViewController != nil) {
//TODO 这个判断有待测试 下面的情况用的不多
if ([presentedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)presentedViewController;
UIViewController *topVC = nav.topViewController;
showViewController = topVC;
} else {
showViewController = presentedViewController;
}
}
//默认不转屏
UIInterfaceOrientationMask orientation = UIInterfaceOrientationMaskPortrait;
BOOL shouldAutorotate = [self shouldAutorotate:showViewController];
//如果可转屏,获取转屏方向
if (shouldAutorotate) {
orientation = [showViewController supportedInterfaceOrientations];
} else {
UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
switch (statusBarOrientation) {
case UIInterfaceOrientationLandscapeLeft:
orientation = UIInterfaceOrientationMaskLandscapeLeft;
break;
case UIInterfaceOrientationLandscapeRight:
orientation = UIInterfaceOrientationMaskLandscapeRight;
break;
default:
orientation = UIInterfaceOrientationMaskPortrait;
break;
}
}
return orientation;
}
return UIInterfaceOrientationMaskPortrait;
}
+ (BOOL)shouldAutorotate:(UIViewController *)showViewController {
//从方法列表中判断是否实现了shouldAutorotate方法(因为ViewController里面的实现不靠谱)
Class rotateClass = [showViewController class];
while (rotateClass != nil && rotateClass != [UIViewController class] && [rotateClass isSubclassOfClass:[UIViewController class]]) {
unsigned int methodCount;
Method *methods = class_copyMethodList(rotateClass, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
SEL sel = method_getName(methods[i]);
if (sel == @selector(shouldAutorotate)) {//如果实现了方法,判断是否可转屏
return [showViewController shouldAutorotate];
}
}
rotateClass = [rotateClass superclass];
}
return NO;
}
如果你的APP是tabbar布局可以直接用,如果不是则需要更改rootViewController的转换