Autorotate view inside UITabBarController and UINa

2019-08-20 02:01发布

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!

3条回答
对你真心纯属浪费
2楼-- · 2019-08-20 02:03

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

Rotating the iPhone, and instantiating a new UIViewController

TabBarController and navigationControllers in landscape mode

查看更多
【Aperson】
3楼-- · 2019-08-20 02:18

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.

查看更多
仙女界的扛把子
4楼-- · 2019-08-20 02:27

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
查看更多
登录 后发表回答