views:

2457

answers:

3

My main view controller is a UITabBarController, with 4 UINavigationControllers as the tab bar items. Each navigation bar is a couple of different views that get pushed onto it's stack.

I have a single view that I want autorotated, but I can't get willAnimateFirstHalfOfRotationToInterfaceOrientation to be called within that view controller.

I've tried subclassing my UITabBarController and UINaviationControllers and adding an override for shouldAutorotateToInterfaceOrientation like so:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

Even after that I can't get the view to rotate. I figured maybe the top-most UIViewController (tab and navigation included) has to be able to rotate. Or even every view up the chain. I've tried overriding shouldAutorotateToInterfaceOrientation for every controller but still can't get the view to rotate.

Anyone accomplished this or have any suggestions?

Thanks in advance!

+1  A: 

Besides subclassing your tabBarController as you did overriding houldAutorotateToInterfaceOrientation, you must do the following:

In the viewDidLoad method of the controller in which you want to add a view to be rotated:

self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Add this delegate method in the controller in which you want to add a view to be rotated:

 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    //NSLog(@"didRotateFromInterfaceOrientation");


    if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) ||
       (fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
    {    

     YourAppDelegate *mainDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
 [mainDelegate.tabBarController.view addSubview: viewToBeRotated];

 [viewToBeRotated setHidden:NO];

 return;

}

if(fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
 [viewToBeRotated removeFromSuperview];
 [self.view setHidden:NO];
}

}

You may also want to add the following method:

- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
            duration:(NSTimeInterval)duration {

if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
 //self.view = self.portrait;
 YourAppDelegate *mainDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
 [viewToBeRotated removeFromSuperview];
 mainDelegate.tabBarController.view.transform = CGAffineTransformIdentity;
 mainDelegate.tabBarController.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
 mainDelegate.tabBarController.view.bounds = CGRectMake(0.0, 0.0, 300.0, 480.0);

}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
 YourAppDelegate *mainDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
 [mainDelegate.tabBarController.view addSubview: viewToBeRotated];
 mainDelegate.tabBarController.view.transform = CGAffineTransformIdentity;
 mainDelegate.tabBarController.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
 mainDelegate.tabBarController.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{


//self.view = self.portrait;
     YourAppDelegate *mainDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
     [viewToBeRotated removeFromSuperview];
     mainDelegate.tabBarController.view.transform = CGAffineTransformIdentity;
     mainDelegate.tabBarController.view.transform = CGAffineTransformMakeRotation(degreesToRadian(180));
     mainDelegate.tabBarController.view.bounds = CGRectMake(0.0, 0.0, 300.0, 480.0);
    }
    else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
     YourAppDelegate *mainDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
     [mainDelegate.tabBarController.view addSubview: viewToBeRotated];
     mainDelegate.tabBarController.view.transform = CGAffineTransformIdentity;
     mainDelegate.tabBarController.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
     mainDelegate.tabBarController.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
    }
}

You may also want to take a look at

http://stackoverflow.com/questions/730799/rotating-the-iphone-and-instantiating-a-new-uiviewcontroller

http://stackoverflow.com/questions/756536/tabbarcontroller-and-navigationcontrollers-in-landscape-mode-episode-ii

unforgiven
I'm actually swapping out two views. I tried setting the autoResizingMask, but it still doesn't work. The other two methods you suggest should be taken care of by my - willAnimateFirstHalfOfRotationToInterfaceOrientation method. It swaps out self.view based on the orientation. That method never even gets called.
Rob
A: 

subclassing UITabBarController and overriding this method worked:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

I think my real problem was XCode not compilingthe updated code. I did Build clean, touch and restarted XCode and the simulator and the changes finally took.

Rob
This would let all view controllers to be rotate-able, I guess.
Felix
A: 

You can use a SubClassed UITabBarController (or use an addition) that asks the selected navigationController for the visibleViewController's response to rotation request:

@implementation RotatingTabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        if([self.selectedViewController isKindOfClass:[UINavigationController class]]){
           return [[(UINavigationController*)self.selectedViewController visibleViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation];
        } else {
           return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
        }
}
@end
Felix
oops, only saw now that this is an old question
Felix
subclassing UITabBarController is discouraged by apple.
hanno