iOS强制横屏总结

总体方向两点:
  • model下,present方式推出界面。
  • push横屏,带tabbar、navigation,且一个item下所有控制器对应的只有一个根navigation。

接下来说说push方式强制旋转横屏时遇到的坑吧.....

遇到的问题描述:
  • 横着,竖屏切换到横屏,是否“锁定竖屏”,都会偶尔造成无法旋转至横屏,iOS8表现较明显。
  • 横着或竖着,切换到横屏,挂起,再进入横屏,退出,再进入横屏,反复切换,偶尔会导致无法横屏,返回上竖屏时,界面返回了,但横屏无法返回。
  • 横竖屏来回切换,跳转,iOS8下,横屏控制器,竖屏控制器中init方法,横屏中viewWillDisapper、viewWillApper,调用顺序会乱,与iOS7、9执行的顺序不一样,个人感觉应该是push强制横屏或都是同一个navigation导致的原因吧。
小总结下:
  • 由于该项目横屏中有来回跳转,到处跳转的,一个item下对应的根控制下又只能是同一个navigation,分享模块又是基于tabbar上的navigation推出的,分享模块无回调,导致我瞻前顾后的,一直盯着push方式到底是否可以强制旋转屏幕........百般绞尽脑汁的研究

  • 思来想去的,就参考了爱奇艺横屏播放视频的方式,横屏中的跳转都先回到竖屏播放控制器中跳转,相当于横屏中跳转多了一层过渡控制器;竖屏返回,应该是返回根控制器,所以,横屏应该是一个新的navigation,而分享都是在横屏中处理的。而我这项目中,分享的列表是在tabbar上的navigation加在windows上的,分享跳转都是基于tabbar的navigation,故无法再新建navigation,否则会引发一系列问题,比如无法跳转至首页,基本上各种在横屏里面的老代码跳转方式都不行了。

故此,我又回到全部push方式继续坑........

因为我也不想啊,如果用present方式涉及改动的代码模块太多了.....

其实有点不明白的是,产品为何如此设计:横屏和竖屏,全模块之间的跳转,试问这样真的好吗.........

接下来分析下push方式,仅限于参考和积累问题吧:

解决方案:

先说下思路吧:

1.实时的更新当前应用所支持的方向,手动调用方法-    (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
2.把当前控制器的方向给到当前navigation,一定要保证统一,不能乱套,否则会导致界面来回跳转错乱的问题;
3.及时刷新当前控制器,手动调用方法[UIViewController attemptRotationToDeviceOrientation]。

一、 present方式:
就不多说了,调用系统的三个方法,基本上没什么问题。

二、push方式:

  • 基类tabbar代码:
    #pragma mark - - orientation
    // 是否支持转屏
    - (BOOL)shouldAutorotate
    {
    return [self.selectedViewController shouldAutorotate];
    }
    // 返回nav栈中的最后一个对象支持的旋转方向
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations
    {
    return [self.selectedViewController supportedInterfaceOrientations];
    }
    // 返回nav栈中最后一个对象,坚持旋转的方向
    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
    {
    return [self.selectedViewController preferredInterfaceOrientationForPresentation];
    }

  • 基类navigation代码:
    //旋转方向 默认竖屏
    @property (nonatomic , assign) UIInterfaceOrientation interfaceOrientation;
    @property (nonatomic , assign) UIInterfaceOrientationMask interfaceOrientationMask;

    #pragma mark - - orientation
    //设置是否允许自动旋转
    - (BOOL)shouldAutorotate {
        return YES;
    }
    
    //设置支持的屏幕旋转方向
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
      return self.interfaceOrientationMask;
    }
    
    //设置presentation方式展示的屏幕方向
    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
      return self.interfaceOrientation;
    }
    
  • 基类BaseViewController代码:
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    [UIViewController attemptRotationToDeviceOrientation];
    }

  • AppDelegate代码
    @property (assign , nonatomic) BOOL isForceLandscape;
    @property (assign , nonatomic) BOOL isForcePortrait;

    -(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
      if (self.isForceLandscape) {
          return UIInterfaceOrientationMaskLandscape;
      }else if (self.isForcePortrait){
          return UIInterfaceOrientationMaskPortrait;
      }
      return UIInterfaceOrientationMaskPortrait;
    }
    
  • 横屏viewController代码:
    重点说明:
    1.此处需要手动调用
    - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
    且设置当前 应用只支持横屏;
    因为,该方法在viewWillAppear之后执行的。
    2.更新了支持的方向后,记得刷新下控制器,调用:
    [UIViewController attemptRotationToDeviceOrientation];
    否则,[UIScreen mainScreen].bounds的size不是你期望的;self.view.frame/bounds都不是期望的。
    3.其实网上说的一些普通的方式实现横屏,问题多,更多的是因为self.view.frame/bounds/[UIScreen mainScreen].bounds没有及时更新的。

    - (void)viewWillAppear:(BOOL)animated
      {
        [super viewWillAppear:animated];
        //强制旋转竖屏
        [self forceOrientationLandscape];
        CKNavigationController *navi = (CKNavigationController *)self.navigationController;
        [self.navigationController setNavigationBarHidden:YES animated:animated];
        navi.interfaceOrientation =   UIInterfaceOrientationLandscapeRight;
        navi.interfaceOrientationMask = UIInterfaceOrientationMaskLandscapeRight;
    
        //强制翻转屏幕,Home键在右边。
        [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"];
        //刷新
        [UIViewController attemptRotationToDeviceOrientation];
    }
    

  重点说明:
  1.离开横屏时、横屏中跳转,记得强制旋转至竖屏;
  2.如果没有及时旋转至横屏,会导致[UIScreen mainScreen].bounds没有及时更新,从而影响其它模块的布局问题;

 - (void)viewWillDisappear:(BOOL)animated 
  {
    [super viewWillDisappear:animated];
     //强制旋转竖屏
    [self forceOrientationPortrait];
    CKNavigationController *navi = (CKNavigationController *)self.navigationController;
    navi.interfaceOrientation = UIInterfaceOrientationPortrait;
    navi.interfaceOrientationMask = UIInterfaceOrientationMaskPortrait;

     //设置屏幕的转向为竖屏
    [[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];
    //刷新
    [UIViewController attemptRotationToDeviceOrientation];
   }

  #pragma  mark 横屏设置
  //强制横屏
- (void)forceOrientationLandscape
  {
    CKAppDelegate *appdelegate=(CKAppDelegate *)[UIApplication sharedApplication].delegate;
    appdelegate.isForceLandscape=YES;
    appdelegate.isForcePortrait=NO;
    [appdelegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
  }

  //强制竖屏
 - (void)forceOrientationPortrait
  {
    CKAppDelegate *appdelegate=(CKAppDelegate *)[UIApplication sharedApplication].delegate;
    appdelegate.isForcePortrait=YES;
    appdelegate.isForceLandscape=NO;
    [appdelegate application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:self.view.window];
  }

- (BOOL)prefersStatusBarHidden{
    return YES;
}
感受
  • 网上找了很多种方法,关于
    这个方法有人说上架可能会被拒,虽然是间接调用私有方法。
    但这个方法经过多轮测试,其实不是有用的,不靠谱,只要按照我上面说的步骤测试,绝对会有bug的,故此不建议大家使用该方法。

     - (void)interfaceOrientation:(UIInterfaceOrientation)orientation{
      if([[UIDevicecurrentDevice] respondsToSelector:@selector(setOrientation:)]) {        
          SEL selector  =NSSelectorFromString(@"setOrientation:");
          NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];     
          [invocation setSelector:selector];        
          [invocation setTarget:[UIDevicecurrentDevice]];
          intval = orientation;
          // 从2开始是因为0 1 两个参数已经被selector和target占用
          [invocation setArgument:&val atIndex:2];                                                     
          [invocation invoke];   
      }}
    

以上所述,支持iOS7、8、9系统,经iphone \iPod测试过,但貌似iOS8从横屏挑战至其它竖屏的界面,偶尔会有问题,概率很小,不影响。
原因:可能是iOS8 SDK与其它不同吧。

更新iOS8的问题:

   iOS8-8.4,横屏跳转至其它界面,最好延迟跳转,不然其它界面的viewWillApper会比横屏的viewWillDisApper先执行,导致无法旋转回来。
   CGFloat timef = 0.8;
    //主要是转屏之后view的再次旋转
    if (kSystemVersion>8||kSystemVersion<8.4) {
        self.view.hidden = YES;
        [self viewWillDisappear:NO];
        timef = 0.1;
    }
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, timef*NSEC_PER_SEC);
    dispatch_after(time, dispatch_get_main_queue(), ^{
        dispatch_async(dispatch_get_main_queue(), ^(){
           //跳转界面
        });
    });

参考资料:
http://www.cocoachina.com/bbs/read.php?tid=244119

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容