原文链接https://my.oschina.net/huqiji/blog/3031940第一种方法会出现无法转屏的问题,我就没有列出来,大家想看的话就去原文里自己去试吧,我这边用的是第二种,亲测有效,废话不多说直接上代码。
第一种解决方案(不推荐,直接跳过看第二种解决方案):
//强制转屏
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation{
if([[UIDevicecurrentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector =NSSelectorFromString(@"setOrientation:");
NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevicecurrentDevice]];intval = orientation;// 从2开始是因为0 1 两个参数已经被selector和target占用
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}}
强制横屏:
[self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
强制竖屏:
[self interfaceOrientation:UIInterfaceOrientationPortrait];
只在某一个界面提供转屏的解决方法如下AppDelegate.m下操作
-(UIInterfaceOrientationMask)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window {
NSLog(@"0000000---------%@",NSStringFromClass([[selftopViewController]class]));
if([NSStringFromClass([[selftopViewController]class]) isEqualToString:@"想要提供转屏的控制器的名字"])
{
//横屏
returnUIInterfaceOrientationMaskLandscapeRight;
}
//竖屏
returnUIInterfaceOrientationMaskPortrait;
}
/获取界面最上层的控制器
- (UIViewController*)topViewController {
return[selftopViewControllerWithRootViewController:[UIApplicationsharedApplication].keyWindow.rootViewController];
}
//一层一层的进行查找判断
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if([rootViewController isKindOfClass:[UITabBarControllerclass]]) {UITabBarController* tabBarController = (UITabBarController*)rootViewController;return[selftopViewControllerWithRootViewController:tabBarController.selectedViewController];
}elseif([rootViewController isKindOfClass:[UINavigationControllerclass]]) {
UINavigationController* nav = (UINavigationController*)rootViewController;return[selftopViewControllerWithRootViewController:nav.visibleViewController]; }elseif(rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return[selftopViewControllerWithRootViewController:presentedViewController];
}else{
returnrootViewController;
}
}
如果你的应用的根控制器是Nav就把下面这段代码放到Nav根控制器下,如果是TabVC放到TabVC的下面
- (BOOL)shouldAutorotate{returnYES;}- (UIInterfaceOrientationMask)supportedInterfaceOrientations{returnUIInterfaceOrientationMaskPortrait;}
然后在你想横屏的控制器加上这段代码,基本上横屏问题就可以搞定了,前提是你的这个控制器是moda出来的,如果是push的话就要使用上文提到的强制横竖屏的方法,下面这段代码是不起作用的
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return(toInterfaceOrientation ==UIInterfaceOrientationLandscapeRight);
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
returnUIInterfaceOrientationMaskLandscapeRight;
}
第二种解决方案:
灵活设置横竖屏,不用区分Push还是Present,都是可以设置。
第一步:
在AppDelegate.h中添加旋转属性/**
* 是否允许转向
*/@property(nonatomic,assign)BOOLallowRotation;
在AppDelegate.m中添加转屏的代理方法
- (UIInterfaceOrientationMask)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(nullableUIWindow*)window{
if(self.allowRotation ==YES)
{
//横屏
returnUIInterfaceOrientationMaskLandscape;
}else{
//竖屏
returnUIInterfaceOrientationMaskPortrait;
}
}
第二步:
设置横竖屏的核心方法,我是直接把这个方法添加到了UIDevice的分类中,代码如下:
UIDevice+TFDevice.h :
#import<UIKit/UIKit.h>@interfaceUIDevice(TFDevice)/**
* @interfaceOrientation 输入要强制转屏的方向
*/+ (void)switchNewOrientation:(UIInterfaceOrientation)interfaceOrientation;@end
UIDevice+TFDevice.m :
#import"UIDevice+TFDevice.h"
@implementationUIDevice(TFDevice)
+ (void)switchNewOrientation:(UIInterfaceOrientation)interfaceOrientation{
NSNumber*resetOrientationTarget = [NSNumbernumberWithInt:UIInterfaceOrientationUnknown]; [[UIDevicecurrentDevice] setValue:resetOrientationTarget forKey:@"orientation"];NSNumber*orientationTarget = [NSNumbernumberWithInt:interfaceOrientation];
[[UIDevicecurrentDevice] setValue:orientationTarget forKey:@"orientation"];
}
@end
第三步:
在需要设置横屏的控制器的ViewDidLoad中添加下面代码:
- (void)viewDidLoad {
[superviewDidLoad];
AppDelegate * appDelegate = (AppDelegate *)[UIApplicationsharedApplication].delegate;//允许转成横屏
appDelegate.allowRotation =YES;//调用横屏代码[UIDeviceswitchNewOrientation:UIInterfaceOrientationLandscapeRight];
}
第四步 (针对Push出的控制器来说):
需要注意的是push过去的时候变成横屏,pop出去的时候在设置竖屏,此时最好禁用系统的侧滑返回手势。
-(void)viewWillAppear:(BOOL)animated{
[superviewWillAppear:animated];//禁用侧滑手势方法self.navigationController.interactivePopGestureRecognizer.enabled =NO;
}
-(void)viewWillDisappear:(BOOL)animated{
[superviewWillDisappear:animated];//禁用侧滑手势方法self.navigationController.interactivePopGestureRecognizer.enabled =YES;
}
第五步:
push控制器:
//点击导航栏返回按钮的时候调用,所以Push出的控制器最好禁用侧滑手势:
AppDelegate * appDelegate = (AppDelegate *)[UIApplicationsharedApplication].delegate;appDelegate.allowRotation =NO;//关闭横屏仅允许竖屏//切换到竖屏[UIDeviceswitchNewOrientation:UIInterfaceOrientationPortrait]; [self.navigationController popViewControllerAnimated:YES];
present控制器:
AppDelegate * appDelegate = (AppDelegate *)[UIApplicationsharedApplication].delegate;appDelegate.allowRotation =NO;//关闭横屏仅允许竖屏//切换到竖屏[UIDeviceswitchNewOrientation:UIInterfaceOrientationPortrait]; [selfdismissViewControllerAnimated:YEScompletion:nil];
第六步: 上图