iOS中单个控制器横屏切换的研究

在项目中遇到了一个问题,app中有两个控制器要求可以切换横屏,研究了半天,终于找到了解决办法.

在AppDelegate中写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- ( UIInterfaceOrientationMask )application:( UIApplication  *)application supportedInterfaceOrientationsForWindow:( UIWindow  *)window{
     NSUInteger  orientations =  UIInterfaceOrientationMaskAllButUpsideDown ;
     if ( self .window.rootViewController){
         UIViewController  *presentedViewController = [ self  topViewControllerWithRootViewController: self .window.rootViewController];
         orientations = [presentedViewController supportedInterfaceOrientations];
     }
     return  orientations;
}
 
- ( UIViewController *)topViewControllerWithRootViewController:( UIViewController *)rootViewController {
     if  ([rootViewController isKindOfClass:[ UITabBarController  class ]]) {
         UITabBarController * tabBarController = ( UITabBarController *)rootViewController;
         return  [ self  topViewControllerWithRootViewController:tabBarController.selectedViewController];
     else  if  ([rootViewController isKindOfClass:[ UINavigationController  class ]]) {
         UINavigationController * navigationController = ( UINavigationController *)rootViewController;
         return  [ self  topViewControllerWithRootViewController:navigationController.visibleViewController];
     else  if  (rootViewController.presentedViewController) {
         UIViewController * presentedViewController = rootViewController.presentedViewController;
         return  [ self  topViewControllerWithRootViewController:presentedViewController];
     else  {
         return  rootViewController;
     }
}


再到各个控制器中写上要旋转的方向

1
2
3
- ( UIInterfaceOrientationMask )supportedInterfaceOrientations{
     return  UIInterfaceOrientationMaskPortrait ;
}


但目前看来还是不够完美,还有两个问题:

  1. 在一个界面切换横屏后再pop回来,发现前一个界面也变成横屏了,必须再转动手机才能正常;

  2. 如果手动点击按钮切换横屏竖屏的话,暂时无法屏蔽自动横屏(重力感应);

    代码在这里:https://github.com/XanderXu/RotateOneVC



    正常竖屏:

1471190499252510.png

转动手机,界面不变


1471190496837183.png

哈哈,经过研究,手动切换横屏界面的bug已经消除了.(setOrientation是私有方法,上架可能会被拒,也可能没问题)

看代码

```objc

-(void)viewWillDisappear:(BOOL)animated {

    //界面消失时,切换回竖屏,不影响前一个/后一个控制器的界面,也不影响输入法....

    self.portrait = YES;

    SEL selector = NSSelectorFromString(@"setOrientation:");

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];

    [invocation setSelector:selector];

    [invocation setTarget:[UIDevice currentDevice]];

    int val = UIDeviceOrientationPortrait;

    //2开始是因为0 1 两个参数已经被selectortarget占用

    [invocation setArgument:&val atIndex:2];

    [invocation invoke];

}

- (IBAction)rotate:(id)sender {    

    

    if ([[UIDevice currentDevicerespondsToSelector:@selector(setOrientation:)]) {

        if (self.isPortrait) {//当前是竖屏,则切换为横屏

            self.portrait = false;

            [[UIDevice currentDeviceperformSelector:@selector(setOrientation:) withObject:[NSNumber numberWithInteger:UIInterfaceOrientationMaskLandscapeLeft]];

        }else {//当前是横屏,则切换为竖屏

            self.portrait = YES;

            SEL selector = NSSelectorFromString(@"setOrientation:");

            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];

            [invocation setSelector:selector];

            [invocation setTarget:[UIDevice currentDevice]];

            int val = UIDeviceOrientationPortrait;

            //2开始是因为0 1 两个参数已经被selectortarget占用

            [invocation setArgument:&val atIndex:2];

            [invocation invoke];

        }

    }

    

}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {

    if (self.isPortrait) {//当前竖屏不让自动切换,只能保持竖屏

        return UIInterfaceOrientationMaskPortrait;

    }else {//当前横屏不让自动切换,只能保持横屏

        return UIInterfaceOrientationMaskLandscape;

    }

}


```


关于屏幕旋转的一些问题,可以看这里的讲解:

IOS Orientation, 想怎么转就怎么转~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值