iOS 横竖屏切换

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

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

iOS 横竖屏切换_第1张图片
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)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 横竖屏切换)