title: didRotateFromInterfaceOrientation is deprecated in iOS 8
body: <p>Since iOS 8.0, the function <code>didRotateFromInterfaceOrientation</code> becomes deprecated and I now have no idea how to change the orientation of <a href="https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVCaptureVideoPreviewLayer_Class/" rel="nofollow noreferrer">AVCaptureVideoPreviewLayer</a> properly. </p>
  
  <p>According to <a href="https://stackoverflow.com/questions/28787165/">&quot;interfaceOrientation&quot; is deprecated in iOS 8, How to change this method Objective C</a>, I have the following working code to get the <code>AVCaptureVideoOrientation</code> based on <code>statusBarOrientation</code>: </p>
  
  <pre><code>- (AVCaptureVideoOrientation)getOrientation {
      // Translate the orientation
      switch ([[UIApplication sharedApplication] statusBarOrientation]) {
          case UIInterfaceOrientationPortrait:
              return AVCaptureVideoOrientationPortrait;
          case UIInterfaceOrientationPortraitUpsideDown:
              return AVCaptureVideoOrientationPortraitUpsideDown;
          case UIInterfaceOrientationLandscapeLeft:
              return AVCaptureVideoOrientationLandscapeLeft;
          case UIInterfaceOrientationLandscapeRight:
              return AVCaptureVideoOrientationLandscapeRight;
          default:
              return AVCaptureVideoOrientationPortrait;
      }
  }
  </code></pre>
  
  <p>I need to call this following function when the orientation is changed: </p>
  
  <pre><code>[self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
  </code></pre>
  
  <p>But I don't know where is the right place to put it. </p>
  
  <h3>Attempt 1</h3>
  
  <p>Since <code>didRotateFromInterfaceOrientation</code> is deprecated and Apple suggest  to use <code>viewWillTransitionToSize:withTransitionCoordinator:</code>, this seems natural to try:</p>
  
  <pre><code>- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id&lt;UIViewControllerTransitionCoordinator&gt;)coordinator
  {
      [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
      [coordinator animateAlongsideTransition:nil completion:^(id&lt;UIViewControllerTransitionCoordinatorContext&gt;  _Nonnull context) {
          [self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
      }];
  }
  </code></pre>
  
  <p>But this function doesn't get called if the <code>UIViewController</code> is being presented (seems to be a known bug based on <a href="https://stackoverflow.com/questions/32884147/">&quot;viewWillTransitionToSize:&quot; not called in iOS 9 when the view controller is presented modally</a>). Even if this bug is resolved, there is another problem: orientation change is <strong>not</strong> equivalent to size change. For instance, if a view is presented with <code>UIModalPresentationFormSheet</code> as the following, </p>
  
  <pre><code>SecondViewController *vc = [[SecondViewController alloc] init];
  vc.view.backgroundColor = [UIColor greenColor];
  vc.modalPresentationStyle = UIModalPresentationFormSheet;
  [self presentViewController:vc animated:true completion:nil];
  </code></pre>
  
  <p>the presented view size the same under landscape and portrait mode for iPad: </p>
  
  <p><img src="https://i.stack.imgur.com/1JADS.jpg" height="160"/>
  <img src="https://i.stack.imgur.com/qXpLR.jpg" width="160"/></p>
  
  <p>Therefore, I cannot simply use <code>viewWillTransitionToSize</code>. </p>
  
  <h3>Attempt 2</h3>
  
  <p>I notice that <code>UIDeviceOrientationDidChangeNotification</code> is not deprecated. Great! I tried register a notification with that:</p>
  
  <pre><code>- (void)viewWillAppear:(BOOL)animated
  {
      [super viewWillAppear:animated];
  
      // Some other code to set up the preview layer 
      // ...
  
      [[NSNotificationCenter defaultCenter] addObserver:self
                                               selector:@selector(deviceOrientationDidChange:)
                                                   name:UIDeviceOrientationDidChangeNotification
                                                 object:nil];
      [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  }
  
  - (void)viewWillDisappear:(BOOL)animated
  {
      [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
      [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
  }
  
  - (void)deviceOrientationDidChange:(NSNotification *)notification {
      [self.videoPreviewLayer.connection setVideoOrientation:[self getOrientation]];
  }
  </code></pre>
  
  <p>This is <strong>almost</strong> working and it is so closed! The problem is that when I get the device orientation changed notification, the animation of rotating the view maybe started and maybe not. Or in another word, the return value <code>[[UIApplication sharedApplication] statusBarOrientation]</code> may be incorrect if the device is already rotated up side down but the animation is still pending. </p>
  
  <p>And I don't know what else to try :( Any ideas? </p>