iOS 开发_屏幕旋转的那些坑儿事

【作者前言】:13年入圈,分享些本人工作中遇到的点点滴滴那些事儿,17年刚开始写博客,高手勿喷!以分享交流为主,欢迎各路豪杰点评改进!

1.应用场景:

项目中如涉及视频、直播等功能,经常会用到屏幕旋转的功能进行全屏浏览,但为了提升用户体验、节省开发周期和成本等,有些视图却并不需要支持旋转,需要独立来控制以满足业务需求。

2.实现目标:

开启系统的自动旋转后,通过代码来手动控制某些独立界面的旋转问题。

3.代码说明:

方法一:【网上千篇一律的方法,但是介绍并不多,在这为了方便迅速解决问题,简明扼要的介绍一下,此方法太麻烦?!莫慌!后面有非常简单的方法哦!!!】

Tip:此处有雷区!!!经测试,并不是说直接重写这两个方法就一定会有效果的!因为实际工程中经常会有这样的控制器层级结构:UITabBarController - UINavigationController - UIViewController,这样的控制器结构就需要一层一层的响应,优先级设置顺序Tab-Nav-VC! 如:Tab上设置了不支持设备旋转,则Nav-VC怎么设置都没有效果!
这里举个例子,目的是将旋转的方法最终传递到VC控制器中,让VC中的方向代码生效!具体可根据实际情况进行阻断和传递。

/**在TabViewController中重写方法  可用类扩展直接重写
*/
// 是否支持自动转屏
- (BOOL)shouldAutorotate {
    UIViewController *vc = self.viewControllers[self.selectedIndex];
    if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)vc;
        return [nav.topViewController shouldAutorotate];
    } else {
        return [vc shouldAutorotate];
    }
}
// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    UIViewController *vc = self.viewControllers[self.selectedIndex];
    if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)vc;
        return [nav.topViewController supportedInterfaceOrientations];
    } else {
        return [vc supportedInterfaceOrientations];
    }
}
// 优先显示的屏幕方向(默认的屏幕方向),及只有在RootViewController和当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    UIViewController *vc = self.viewControllers[self.selectedIndex];
    if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)vc;
        return [nav.topViewController preferredInterfaceOrientationForPresentation];
    } else {
        return [vc preferredInterfaceOrientationForPresentation];
    }
}
/**在NavigationController中重写方法  可用类扩展直接重写
*/
// 是否支持自动转屏
- (BOOL)shouldAutorotate {
    return [self.topViewController shouldAutorotate];
}
// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return [self.topViewController supportedInterfaceOrientations];
}
// 优先显示的屏幕方向(默认的屏幕方向),及只有在RootViewController和当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.topViewController preferredInterfaceOrientationForPresentation];
}

之后再在对应的需要控制旋转的VC中重写下面的方法

/**是否允许屏幕旋转
注:只有在该方法返回YES时,下面的方法才会被调用
*/
- (BOOL)shouldAutorotate
{
    return YES;
}
/**屏幕支持旋转的方向
在设备屏幕旋转时,系统会调用 
-(BOOL)shouldAutorotate 方法去检查当前界面是否支持旋转,
只有 -(BOOL)shouldAutorotate 返回 YES 的时候,
-(NSUInteger)supportedInterfaceOrientations 方法才会被调用,
从而确定是否需要旋转界面。
*/
- (NSUInteger)supportedInterfaceOrientations
{
    return (UIInterfaceOrientationMaskAll);
}
// 优先显示的屏幕方向(默认的屏幕方向),及只有在RootViewController和当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}
/**
在iOS5.1及之前通过下面的一个方法即可达到对页面旋转的控制;
但iOS6之后,此方法已经被废弃,目前市面基本已经放弃了兼容iOS6,所以只是做个简单介绍,扩宽下知识层面
*/
/*
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

方法一太繁琐了???好麻烦哦!~没关系,往下看!方法二傻瓜级的方法定能助你完成功能!

方法二:在 iOS 6 中,UIApplicationDelegate 协议中添加了一个可以指定 UIWindow 中的界面的屏幕方向的方法:
  • (NSUInteger)application:(UIApplication *)application
    supportedInterfaceOrientationsForWindow:(UIWindow *)window;
利用好此方法,我们就能够快速解决单独界面的旋转支撑问题!
/**第一步:在AppDelegate或者其Category中的.h文件中添加属性:
isAllowRotation
属性解释:是否允许屏幕旋转
*/
/** 是否支持屏幕旋转*/
@property(nonatomic,assign)BOOL isAllowRotation;

/**第二步:在AppDelegate或者其Category中的.m文件中
添加实现上面iOS 6新增的方法*/
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if (self.isAllowRotation) //支持程序允许的全部旋转
        return UIInterfaceOrientationMaskAll;
    else//不支持旋转,即只能竖屏
    return UIInterfaceOrientationMaskPortrait;
}
/**实际应用
这里本不想写了...但为了把 “复制粘贴” 的程序精神发扬光大,还是写一写吧()
*/
//在支持旋转的VC中导入头文件:
#import "AppDelegate.h"
//并调用一下支持旋转的方法:
[(AppDelegate *)[UIApplication sharedApplication].delegate setIsAllowRotation:YES];

/**_______________华丽的分界线_____________________*/
//在不支持旋转的VC中导入头文件:
#import "AppDelegate.h"
//并调用一下不支持旋转的方法:
[(AppDelegate *)[UIApplication sharedApplication].delegate setIsAllowRotation:NO];

/**更多情况下是指在独立的VC中同时使用,
如我的项目使用场景为:进入播放视频/视讯直播页之后
支持旋转,离开此页面后不支持旋转*/
//在VC的生命周期函数中调用即可(viewWillAppear --- viewWillDisappear等)
方法三:【下下策...也是最暴力的,通过KVC强制设置方向】
-(void)viewWillAppear:(BOOL)animated{
     /** 先将设备方向设置为:UIInterfaceOrientationUnknown,
避免出现直接设置无效的BUG*/
    NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
    [[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
    /** 然后在设置成想要变成的方向*/
    NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
    [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
}

你可能感兴趣的:(iOS 开发_屏幕旋转的那些坑儿事)