Search code examples
iosobjective-cuiviewcontrolleruiinterfaceorientation

How to detect orientation of View Controller


I have three view controller both are which are pushed on the navigation controller which I have subclassed in order to allow rotation in only Second View Controller, I do it like this,

- (BOOL)shouldAutorotate
{    
  if ([self.topViewController isKindOfClass:[SecondViewController class]])
      return YES;

  return NO;
}

I write this piece of code in my Custom Navigation Controller, The problem is that if I open my application in portrait mode and then change the orientation to landscape mode my View Controller does not rotate but even when my Second View Controller opens up it opens in portrait mode although I expect it to open in landscape mode as it supports rotation.

How can I achieve this?


Solution

  • You need to use attemptRotationToDeviceOrientation during navigation. You should override push/pop methods to call attemptRotationToDeviceOrientation with a small UI delay (dispatch_async)

    @implementation CustomNavigationController
    
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        [super pushViewController:viewController animated:animated];
    
        [self updateOrientaion];
    }
    
    - (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated
    {
        [self updateOrientaion];
    
        return [super popViewControllerAnimated:animated];
    }
    
    
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations
    {
        if ([self.topViewController isKindOfClass:[SecondViewController class]])
            return UIInterfaceOrientationMaskAll;
    
        return UIInterfaceOrientationMaskPortrait;
    }
    
    
    - (void)updateOrientaion
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [UIViewController attemptRotationToDeviceOrientation];
        });
    }
    
    @end
    

    But when you pop to rootViewController of the UINavigationController supportedInterfaceOrientations is called for the rootViewController. So you also need to implement supportedInterfaceOrientations for the FirstViewController

    @implementation FirstViewController
    
    .......
    
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations
    {    
        return UIInterfaceOrientationMaskPortrait;
    }
    
    @end