I'm still looking for a more elegant way to handle this, but I'll share a little hack that has worked for me. If you find something better, please let me know.
An approach that has worked ok for me in apps with complex navigation trees, is to install the custom subclass for the very first navigation controller or very first view controller if you don't have a nav controller that is in your app. that is the one that is going to receive the shouldAutoRotate calls.
It sounds like you have done this already.
Now you need to insert your own logic in the shouldAutoRotate section. What I've done is to use a BOOL in the appDelegate as a place to store if a view controller should autorotate. Basically it works like this:
appDelete:
@property (nonatomic,assign) BOOL allowAutoRotationForThisViewController;
custom navigation controller at head of stack:
- (BOOL)shouldAutorotate {
AppDelegate *a = [[UIApplication sharedApplication] delegate];
return a.allowAutoRotationForThisViewController;
}
rotatable view controller:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
AppDelegate *a = [[UIApplication sharedApplication] delegate];
a.allowAutoRotationForThisViewController = YES:
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
AppDelegate *a = [[UIApplication sharedApplication] delegate];
a.allowAutoRotationForThisViewController = NO:
}
I'm not sure why they changed this in ios6, it seems much more difficult, especially when you have complex navigation structure. I have an app with "slide" type controller at the top of the stack, a tabbar controller and stacks of navigation controllers. Trying to pick through all of those to get a web view on the bottom of the stack to rotate, or get them to respond to the top level controller is very complicated. So I've used this approach.
Now, one thing you have to consider - is that if the BOOL is turned to NO, then no rotation will occur - so one gotcha is if your rotatable view controller pops back to its parent while its rotated. Then the parent will be rotated and the rotatable view controller will have set the rotation value back to no. I solved this in my approach by preventing it to dismiss unless it was in portrait mode - basically I disabled the "back" button in landscape mode.
this works like this:
- view comes on screen - sets rotation to YES
- rotation occurs
- at this point, the view that is being rotated will get the following selector call:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
so, inside of that call, you would configure your local view and do anything you need to do to setup the view for the orientation change - like self.navigationController.hidesBackButton = YES;
hope that helps, and like I said, its a bit of a hack and I'm looking for something more elegant.
best of luck