0

I'm trying to allow some views to rotate in my app (just two), I've done this before successfully, subclassing UINavigationcontroller and overriding the corresponding methods. The problem this time is that I'm using a third party project that creates the navigation controller from a .xib file (not programmatically). I changed the class in the .xib file in order to use my custom navigation controller and it does, but for some reason is ignoring override methods like shouldAutorotate and supportedInterfaceOrientations

Any ideas?

Thanks

aprunedamtz
  • 169
  • 2
  • 10

1 Answers1

0

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

CocoaEv
  • 2,984
  • 20
  • 21
  • Thanks for your answer, is very complete. However, the problem I'm facing is that the shouldAutorotate method of my custom class is never being called. In my rotatable view controller I print the value of the navigation controller (to console) in order to know if is using my custom class and seems to be right. But for some reason (I think related with the navigation controller coming from a .xib file) overrided methods in my custom class are not being called. The problem actually is that I opened all orientations in target configuration but want to avoid rotation in some of the views – aprunedamtz Mar 15 '13 at 19:46
  • Please ignore my previous comment. Methods in my custom class were working fine, the problem was a third party VC that added my nav controller like this: [self.view addSubview:[customNavController view]], I got the idea because of this post: http://stackoverflow.com/questions/12775265/ios-6-shouldautorotate-is-not-being-called . So, I wanted to change autorotation behavior of that first VC in some view controllers. I used your code to override the third party VC (instead of a custom navController) and worked like a charm. Thanks! – aprunedamtz Mar 15 '13 at 20:56