2013-03-08 78 views
8

我有以下视图控制器设置推:在iOS6的,麻烦迫使视图控制器某些interfaceOrientation当栈

viewController1能够自由旋转到任何方位除了肖像倒挂。

viewController2被推到viewController1之上,我想它是相同的方向viewController1是,我希望它不能够旋转。

viewController3被推到viewController2之上。我希望viewController3处于纵向模式。

我有很多问题试图在iOS6中完成这一点(还没有在iOS5中尝试过)。首先,我已经创建了自己的导航控制器,并把它下面:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 
{ 
    return [self.topViewController preferredInterfaceOrientationForPresentation]; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    return [self.topViewController supportedInterfaceOrientations]; 
} 

- (BOOL) shouldAutorotate 
{ 
    return [self.topViewController shouldAutorotate]; 
} 

我已经尝试了很多这些东西的不同组合就知道结果。主要是我在挣扎的地方是,如果vc2处于风景中,强制将vc3呈现为肖像。任何帮助,将不胜感激。

回答

12

你在这里试图做的是打架。你所描述的并不是iOS 6中导航控制器体系结构的工作原理。如果你想显示视图控制器的视图和强制旋转,使用一个呈现的视图控制器。这是唯一的时候preferredInterfaceOrientationForPresentation是有意义的,并且您的视图控制器的supportedInterfaceOrientations将被实际咨询,因为被呈现,它将在界面的根部。

+1

那么你的意思是我不得不推动它作为模态观来强制轮换?我无法将它推到导航堆栈上并强制它? – 2013-03-08 19:05:19

+2

是的,除了你所说的方式之外,你必须将它呈现为过去被称为模态视图控制器的形式,而不是将其推送到导航堆栈上。呈现的视图控制器可以强制旋转。推到导航堆栈上的视图控制器不能;该应用程序可以动态决定如何在*用户旋转设备*时作出响应,但仅仅将视图控制器推入导航堆栈的操作不会导致应用程序界面旋转。 – matt 2013-03-08 19:10:18

+0

您是否碰巧知道是否有手动方式强制视图控制器在提交后旋转?不是让用户旋转它,而是让它自行旋转? – 2013-03-08 19:14:11

5

我已经解释了另一个不同的答案,它在iOS 6中不支持将新视图控制器推到导航控制器上时的旋转。您可以构造关于补偿性的旋转的规则(即,如果用户旋转设备会发生什么情况),但是您不能旋转接口。 iOS 6高兴地让你旋转的唯一情况是在呈现或解散视图控制器(presentViewController:animated:dismissViewControllerAnimated:)时。

但是,您可以像使用导航控制器那样使用一个呈现的视图控制器,使其类似看起来像。我做了一个电影展示了我的意思:

http://youtu.be/O76d6FhPXlE

现在,这是不以任何方式完全完美。状态栏没有旋转动画,并且在两个视图之间有一种黑色的“闪烁” - 这是故意的,因为它在那里掩盖了真正的。真正发生的是真实的两个差异导航控制器和三个视图控制器,如故事板的此屏幕截图所示。

enter image description here

我们拥有的是:

  • 一个导航控制器子类设置为纵向,其根视图控制器

  • 第二导航控制器子类设置为横向,和它的根视图控制器,它是黑色的,作为媒介发挥作用

  • 第三视图控制器被推到第二导航控制器的堆栈

当用户请求去“向前”从第一视图控制器,我们呈现第二导航控制器,从而在看到黑色视图控制器暂时,但是我们立即第三个视图控制器。所以我们得到了强制旋转,以及一种黑色闪光和一个推动画。当用户点击第三个视图控制器中的“后退”按钮时,我们会反转该过程。

所有的过渡代码都在黑色视图控制器(ViewControllerIntermediary)中。我试图调整它给予最满意的动画我可以:

@implementation ViewControllerIntermediary { 
    BOOL _comingBack; 
} 

- (void) viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationController.delegate = self; 
} 

-(void)navigationController:(UINavigationController *)nc 
     willShowViewController:(UIViewController *)vc 
     animated:(BOOL)anim { 
    if (self == vc) 
     [nc setNavigationBarHidden:YES animated:_comingBack]; 
    else 
     [nc setNavigationBarHidden:NO animated:YES]; 
} 

-(void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    if (!_comingBack) { 
     [self performSegueWithIdentifier:@"pushme" sender:self]; 
     _comingBack = YES; 
    } 
    else 
     [self.navigationController dismissViewControllerAnimated:YES 
      completion:nil]; 
} 
1
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
if ([self.window.rootViewController.presentedViewController isKindOfClass: [SecondViewController class]]) 
{ 
    SecondViewController *secondController = (SecondViewController *) self.window.rootViewController.presentedViewController; 

    if (secondController.isPresented) 
     return UIInterfaceOrientationMaskAll; 
    else return UIInterfaceOrientationMaskPortrait; 
} 
else return UIInterfaceOrientationMaskPortrait; 
} 

而对于斯威夫特

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int { 

    if self.window?.rootViewController?.presentedViewController? is SecondViewController { 

     let secondController = self.window!.rootViewController.presentedViewController as SecondViewController 

     if secondController.isPresented { 
      return Int(UIInterfaceOrientationMask.All.toRaw()); 
     } else { 
      return Int(UIInterfaceOrientationMask.Portrait.toRaw()); 
     } 
    } else { 
     return Int(UIInterfaceOrientationMask.Portrait.toRaw()); 
    } 

} 

有关详情,请这个link

相关问题