美文网首页
iOS 开发_屏幕旋转的那些坑儿事

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

作者: iOS_PM_WEB_尛鹏 | 来源:发表于2018-07-26 17:17 被阅读0次

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

    1.应用场景:

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

    2.实现目标:

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

    3.代码说明:

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

    Tip:此处有雷区!!!经测试,并不是说直接重写这两个方法就一定会有效果的!因为实际工程中经常会有这样的控制器层级结构:TabViewController - 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等)
    
    方法三:【下下策...也是最暴力的,通过KVO强制设置方向】
    -(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 开发_屏幕旋转的那些坑儿事

          本文链接:https://www.haomeiwen.com/subject/ltvbmftx.html