美文网首页
iOS 横竖屏切换

iOS 横竖屏切换

作者: 低调的前行者灬 | 来源:发表于2017-05-19 14:51 被阅读0次

    本文只针对单个界面横竖屏界面

    1.首先在TARGETS中将横竖屏勾选上(不用勾选貌似也可以,只不过需要在AppDelegate中,代码控制)

    image.png

    AppDelegate中控制横竖屏的代码如下

    - (UIInterfaceOrientationMask )application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
    {
        //如果设置了allowRotation属性,支持全屏
        if (self.allowRotation) {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
        return UIInterfaceOrientationMaskPortrait;//默认全局不支持横屏
    }
    

    2.主要利用通知来实现,AppDelegate中创建BOOL值allowRotation

    - (void)addNotificationCenter
    {
        //在进入需要全屏的界面里面发送需要全屏的通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startFullScreen) name:@"startFullScreen" object:nil];//进入全屏
        //在退出需要全屏的界面里面发送退出全屏的通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endFullScreen) name:@"endFullScreen" object:nil];//退出全屏
    }
    #pragma mark 进入全屏
    -(void)startFullScreen
    {
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        appDelegate.allowRotation = YES;
    }
    #pragma mark    退出横屏
    -(void)endFullScreen
    {
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        appDelegate.allowRotation = NO;
        //强制归正:
        [[AnyeToolManager shareManager] setOrientationInterfaceOrientationPortrait];
    }
    #pragma mark    禁止横屏
    - (UIInterfaceOrientationMask )application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
    {
        //如果设置了allowRotation属性,支持全屏
        if (self.allowRotation) {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
        return UIInterfaceOrientationMaskPortrait;//默认全局不支持横屏
    }
    

    强制归正的代码:
    1.第一种,据说调用私有变量,可能被拒

    if ([[UIDevice currentDevice]   respondsToSelector:@selector(setOrientation:)]) {
            SEL selector =     NSSelectorFromString(@"setOrientation:");
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
            [invocation setSelector:selector];
            [invocation setTarget:[UIDevice currentDevice]];
            int val =UIInterfaceOrientationPortrait;
            [invocation setArgument:&val atIndex:2];
            [invocation invoke];
        }
    

    2.第二种,利用KVO,目前采用此方法,会不会被拒尚未知,等项目上线后回来更新(项目已上线,用此种方法可以通过审核)

        NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
        [[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
        
        NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
        [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
    

    其实后两行代码就可以满足需求,至于前两行代码的原因,这里有答案http://www.jianshu.com/p/6c45fa2bb970

    3.在需要横屏的控制器的viewWillAppear和viewWillDisappear中分别发送可以横屏和取消横屏的通知

    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];    
        //发送全屏通知
        [[NSNotificationCenter defaultCenter] postNotificationName:@"startFullScreen" object:nil];
        //强制归正
        [[AnyeToolManager shareManager] setOrientationInterfaceOrientationPortrait];
    }
    -(void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        //发送非全屏通知
        [[NSNotificationCenter defaultCenter] postNotificationName:@"endFullScreen" object:nil];
    }
    

    4.搞定,不过有BUG,在横屏模式下,退出到不可以横屏的控制器,会默认先回正,再pop,视觉上不是很好,这个问题正在研究...

    5.另外,在我处理横竖屏切换的过程中,遇到一个问题,切换动画消失,也就是,竖屏到横屏的过程很突然,没有旋转的过程,也算是一个奇葩.经过大量的谷歌百度,竟然搜不到任何相关,好在最后意外解决,也算是惊喜,方法如下

    -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
    {   
        [UIView beginAnimations:@"rotate" context:nil];
        [UIView setAnimationDuration:ReadAnimationLeftRightTimeInterval];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [UIView commitAnimations];//一定要停止,不停止的话,整个APP的所有的动画都会出异常
        });
        
    }
    

    viewWillTransitionToSize:(CGSize)size withTransitionCoordinator方法会在横竖屏切换的时候调用,在这个方法中让UIView的rotate动画beginAnimation,并且切记要执行 [UIView commitAnimations],而且此方法千万不要立即执行,延迟一点时间,不然还是没动画,但如果不执行的话,整个APP的所有的动画都会出异常
    其实这种方法也有好处,就是可以调整横竖屏切换的时间

    [UIView setAnimationDuration:ReadAnimationLeftRightTimeInterval];
    

    我这里的ReadAnimationLeftRightTimeInterval只是个宏,可以根据所需调整

    相关文章

      网友评论

          本文标题:iOS 横竖屏切换

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