15

If I have a pointer to a UIViewController, can I be notified when it changes interfaceOrientation without modifying the code of the controller?

Is my best bet to detect changes in device orientation and then see if the UIViewController will/has rotate(d)?

Ben Flynn
  • 18,524
  • 20
  • 97
  • 142
  • not sure if the question is still actual, but you can use objc method swizzling to add your own code into the `UIViewController`'s code. This should look like exchanging `-didRotateFromInterfaceOrientation:` with your own implementation which has a call to your orientation changed handler method and a call to original implementation – medvedNick Nov 22 '13 at 11:40
  • @medvedNick That seems reasonable. I could call my delegate then call the original implementation. I might be a little worried about potential side effects. – Ben Flynn Nov 22 '13 at 16:00

2 Answers2

16

You can use NSNotificationCenter :

 [[NSNotificationCenter defaultCenter] addObserver:self // put here the view controller which has to be notified
                                         selector:@selector(orientationChanged:)
                                             name:@"UIDeviceOrientationDidChangeNotification" 
                                           object:nil];
- (void)orientationChanged:(NSNotification *)notification{  
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    //do stuff
    NSLog(@"Orientation changed");          
}
Loris1634
  • 659
  • 4
  • 5
  • 4
    Hmm. I think I wasn't clear. I want to know the apparent orientation of a ViewController rather than the device. In other words, my object wants to observe a view controller to see its orientation, which may be different from the device's and may not change when the device changes orientation. This answer is part of what I was implying in the second part of my question. – Ben Flynn Jan 17 '13 at 21:32
3

You can use the willAnimateRotationToInterfaceOrientation:duration: method on your UIViewController and then reposition any UIViews (or any other code) for landscape or portrait. E.g.

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
    // change positions etc of any UIViews for Landscape
  } else {
    // change position etc for Portait
  }

  // forward the rotation to any child view controllers if required
  [self.rootViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
rogchap
  • 933
  • 6
  • 8
  • 2
    Unfortunately this would mean changing the code of the UIViewController. Here I only have a pointer to it and want to observe its behavior. What'd I'd really like to do is be notified when "interfaceOrientation" returns a different value. – Ben Flynn Jan 18 '13 at 00:34
  • 1
    NB: This is deprecated in iOS 8. http://stackoverflow.com/questions/25238620/ios-8-rotation-methods-deprecation-backwards-compatibility – jowie Jul 30 '15 at 16:34