I have an app where I would like to support device rotation in certain views but other don\'t particularly make sense in Landscape mode, so as I swapping the views out I wou
FWIW, here's my implementation of manually setting orientation (to go in your app's root view controller, natch):
-(void)rotateInterfaceToOrientation:(UIDeviceOrientation)orientation{
CGRect bounds = [[ UIScreen mainScreen ] bounds ];
CGAffineTransform t;
CGFloat r = 0;
switch ( orientation ) {
case UIDeviceOrientationLandscapeRight:
r = -(M_PI / 2);
break;
case UIDeviceOrientationLandscapeLeft:
r = M_PI / 2;
break;
}
if( r != 0 ){
CGSize sz = bounds.size;
bounds.size.width = sz.height;
bounds.size.height = sz.width;
}
t = CGAffineTransformMakeRotation( r );
UIApplication *application = [ UIApplication sharedApplication ];
[ UIView beginAnimations:@"InterfaceOrientation" context: nil ];
[ UIView setAnimationDuration: [ application statusBarOrientationAnimationDuration ] ];
self.view.transform = t;
self.view.bounds = bounds;
[ UIView commitAnimations ];
[ application setStatusBarOrientation: orientation animated: YES ];
}
coupled with the following UINavigationControllerDelegate method (assuming you're using a UINavigationController):
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
// rotate interface, if we need to
UIDeviceOrientation orientation = [[ UIDevice currentDevice ] orientation ];
BOOL bViewControllerDoesSupportCurrentOrientation = [ viewController shouldAutorotateToInterfaceOrientation: orientation ];
if( !bViewControllerDoesSupportCurrentOrientation ){
[ self rotateInterfaceToOrientation: UIDeviceOrientationPortrait ];
}
}
That takes care of rotating the root view according to whether an incoming UIViewController supports the current device orientation. Finally, you'll want to hook up rotateInterfaceToOrientation to actual device orientation changes in order to mimic standard iOS functionality. Add this event handler to the same root view controller:
-(void)onUIDeviceOrientationDidChangeNotification:(NSNotification*)notification{
UIViewController *tvc = self.rootNavigationController.topViewController;
UIDeviceOrientation orientation = [[ UIDevice currentDevice ] orientation ];
// only switch if we need to (seem to get multiple notifications on device)
if( orientation != [[ UIApplication sharedApplication ] statusBarOrientation ] ){
if( [ tvc shouldAutorotateToInterfaceOrientation: orientation ] ){
[ self rotateInterfaceToOrientation: orientation ];
}
}
}
Finally, register for UIDeviceOrientationDidChangeNotification notifications in init or loadview like so:
[[ NSNotificationCenter defaultCenter ] addObserver: self
selector: @selector(onUIDeviceOrientationDidChangeNotification:)
name: UIDeviceOrientationDidChangeNotification
object: nil ];
[[ UIDevice currentDevice ] beginGeneratingDeviceOrientationNotifications ];