1

我有一个导航控制器,它一次显示两个视图控制器。它们是分层的,并且最前面的控制器可以被拖拽到下面显示控制器。 我的应用程序代理已配置,因此应用程序只会在后面的视图显示时允许界面方向,如下所示。防止导航控制器中的一些视图控制器旋转

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
    if (self.revealNavigationController.isViewRevealed) 
    { 
     return UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    return UIInterfaceOrientationMaskPortrait; 
} 

当然,这会导致前后视图控制器在设备旋转时旋转,但我只对旋转后视图控制器感兴趣。 有没有什么办法可以在最前面的视图控制器中完全禁用旋转?

+0

是(这是由在计算器上另一个答案,我现在无法再次找到,遗憾的启发)你的问题是,用户可以揭示后视图,侧向旋转,然后隐藏它,主视图仍然横向,或者主视图即使在屏幕外时也会旋转? – axiixc 2013-04-30 20:26:14

+0

@axiixc问题在于主视图在屏幕外旋转。视图控制器并非真正支持方向更改,因此如果您显示后视图,旋转到横屏,旋转回肖像并再次隐藏后视图以显示主视图,主视图会混乱。理想情况下,我希望主要视图不可能旋转。这将解决你提到的两个问题。因此,如果用户显示后视图,侧向旋转并隐藏它,主视图仍然是肖像。 – simonbs 2013-04-30 20:30:29

回答

0

由axiixc建议的解决方案通常更好,这取决于你的问题,你应该look at his answer但是,这并没有解决我的问题。我有一个UINavigationController,其中我将视图控制器的视图作为索引0的子视图插入。这样,视图就位于后面。然后我做了可拖动的拖拽,这样当它拖拽时,它会在后面显示视图。然后,最前面的视图将随导航栏一起移动。 正如axiixc所建议的那样,我没有设法让它与视图控制器遏制API引入iOS 5一起工作。

取而代之,我从导航控制器中删除了视图,并在启动应用程序时将其直接添加到UIWindow,我自己处理了此视图的旋转并禁用了所有其他视图的旋转(即,我禁用了该视图导航控制器)。

这是我如何添加视图-application:didFinishLaunchingWithOptions:

self.revealViewController = [[RevealViewController alloc] init]; 
[self.window insertSubview:self.revealViewController.view atIndex:0]; 

后,立刻,我注册了UIDeviceOrientationDidChangeNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

didRotate:看起来是这样的:

- (void)didRotate:(NSNotification *)notification 
{ 
    // Only rotate if the view is revealed 
    if (self.revealNavigationController.isViewRevealed) 
    { 
     UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; 
     [self updateForDeviceOrientation:orientation animated:YES]; 
    } 
} 

我打电话-updateForDeviceOrientation:animated:

- (void)updateForDeviceOrientation:(UIDeviceOrientation)orientation animated:(BOOL)animated 
{ 
    CGFloat degrees = 0.0f; 
    switch (orientation) 
    { 
     case UIDeviceOrientationLandscapeLeft: 
      degrees = 90.0f; 
      break; 
     case UIDeviceOrientationLandscapeRight: 
      degrees = -90.0f; 
      break; 
     case UIDeviceOrientationPortrait: 
      degrees = 0.0f; 
      break; 
     default: 
      break; 
    } 

    CGFloat duration = (animated) ? [UIApplication sharedApplication].statusBarOrientationAnimationDuration : 0.0f; 

    __weak typeof(self) weakSelf = self; 
    [UIView animateWithDuration:duration animations:^{ 
     // Rotate view 
     weakSelf.revealViewController.view.transform = CGAffineTransformIdentity; 
     weakSelf.revealViewController.view.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees)); 

     // Resize view for rotation 
     CGFloat width, height; 
     if (UIDeviceOrientationIsLandscape(orientation)) 
     { 
      width = MAX(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
      height = MIN(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
     } 
     else 
     { 
      width = MIN(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
      height = MAX(CGRectGetWidth(weakSelf.revealViewController.view.bounds), CGRectGetHeight(weakSelf.revealViewController.view.bounds)); 
     } 

     CGSize newSize = CGSizeMake(width, height); 

     CGRect viewBounds = weakSelf.revealViewController.view.bounds; 
     viewBounds.size = newSize; 
     weakSelf.revealViewController.view.bounds = viewBounds; 

     CGRect viewFrame = weakSelf.revealViewController.view.frame; 
     viewFrame.size = newSize; 
     weakSelf.revealViewController.view.bounds = viewFrame; 
    }]; 
} 
0

是的,看看UIViewController中的-supportedInterfaceOrientations方法。您返回一个UIInterfaceOrientationMask位掩码,指定您希望UIViewController子类支持的方向。

+0

我刚刚尝试在'-supportedInterfaceOrientations'中的'-sharedAutorotate'和'UIInterfaceOrientationMaskPortrait'中返回'NO',并将其放在我最前面的一个控制器中。虽然'-supportedInterfaceOrientations'在视图呈现但不旋转时被调用,它似乎被忽略。视图控制器仍然尝试旋转视图并在横向方向上满足自动布局约束。 – simonbs 2013-04-30 20:18:54

+0

'-shaouldAutorotate'不被调用,但。 – simonbs 2013-04-30 20:22:06

1

您需要使用在iOS5中添加的视图控制器包含API。基本上,当你不再需要它参与旋转事件时,你需要做的是删除你的一个视图控制器,并在它再次准备好时再添加它。样品将是...

@implementation AXRotationDemoViewController 

- (id)init 
{ 
    if ((self = [super init])) 
    { 
     self.oneViewController = [[AXLoggingViewController alloc] init]; 
     self.oneViewController.interfaceOrientations = UIInterfaceOrientationMaskPortrait; 

     self.twoViewController = [[AXLoggingViewController alloc] init]; 
     self.twoViewController.interfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown; 
    } 

    return self; 
} 

- (void)viewDidLoad 
{ 
    [self.oneViewController willMoveToParentViewController:self]; 
    [self addChildViewController:self.oneViewController]; 
    [self.view addSubview:self.oneViewController.view]; 
    [self.oneViewController didMoveToParentViewController:self]; 

    [self.twoViewController willMoveToParentViewController:self]; 
    [self addChildViewController:self.twoViewController]; 
    [self.view addSubview:self.twoViewController.view]; 
    [self.twoViewController didMoveToParentViewController:self]; 

    self.oneViewController.view.backgroundColor = [UIColor redColor]; 
    self.twoViewController.view.backgroundColor = [UIColor greenColor]; 

    UIButton * showBackButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [showBackButton setTitle:@"Toggle Back/Front" forState:UIControlStateNormal]; 
    [showBackButton addTarget:self action:@selector(_toggle:) forControlEvents:UIControlEventTouchUpInside]; 
    [showBackButton sizeToFit]; 
    showBackButton.center = self.view.center; 
    [self.view addSubview:showBackButton]; 
} 

- (void)_toggle:(id)sender 
{ 
    if ([self.childViewControllers containsObject:self.oneViewController]) 
    { 
     [self.oneViewController.view removeFromSuperview]; 
     [self.oneViewController removeFromParentViewController]; 
    } 
    else 
    { 
     [self.oneViewController willMoveToParentViewController:self]; 
     [self addChildViewController:self.oneViewController]; 
     [self.view addSubview:self.oneViewController.view]; 
     [self.oneViewController didMoveToParentViewController:self]; 

     UIWindow * window = self.view.window; 
     UIViewController * hack = window.rootViewController; 
     window.rootViewController = nil; 
     window.rootViewController = hack; 
    } 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    CGRect halfScreenFrame = self.view.bounds; 
    halfScreenFrame.size.height /= 2; 

    self.oneViewController.view.frame = halfScreenFrame; 
    self.twoViewController.view.frame = CGRectOffset(halfScreenFrame, 0, halfScreenFrame.size.height); 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    if ([self.childViewControllers containsObject:self.oneViewController]) 
     return self.oneViewController.supportedInterfaceOrientations; 

    return self.twoViewController.supportedInterfaceOrientations; 
} 

@end 

然而,你可能会注意到,有一个真正告诉iOS的没有正式的方式,你已经改变的supportedInterfaceOrientations价值,所以最好的办法是A)使用黑客像我上面的例子强制iOS重做一切,或者b)不要让用户关闭后视图,直到设备再次处于肖像状态。

这里是sample我放在一起,如果这不能解释得很好。

+0

这将是理想的方法,但我没有设法在这种情况下得到这个工作。有关我的解决方案,请参阅http://stackoverflow.com/a/16354167/486845。 – simonbs 2013-05-03 08:02:32

相关问题