Autorotate a single UIViewController in iOS 6 with

2019-01-13 01:58发布

问题:

I have an app that work only in Portrait Mode, but there is a singleView that can display video, so i want that view work also in the landscape mode, but in iOS 6 I can't figure out how I can do it, now I have this:

In AppDelegate.m i have:

self.window.rootViewController = myTabBar;

then in the Summary of the project:

and i found that in iOS 6 to detect the view rotation i have to do this:

- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}

// Tell the system It should autorotate
- (BOOL) shouldAutorotate {
return YES;
}

so i insert the code above only in my UIViewController that I want use also in landscape, but don't work, anyone knows how i can do it? i just want the autorotate when show video.

回答1:

Firstly, your target settings should look like this:

In UITabBarController:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // You do not need this method if you are not supporting earlier iOS Versions
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

-(NSUInteger)supportedInterfaceOrientations
{
    if (self.selectedViewController) 
        return [self.selectedViewController supportedInterfaceOrientations];

    return UIInterfaceOrientationMaskPortrait;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

Inside your ViewController:

a) if you dont want to rotate:

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

- (BOOL)shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

b) if you want to rotate to landscape:

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

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

Edit:

Other solution is to implement this method inside AppDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSUInteger orientations = UIInterfaceOrientationMaskAll;

    if (self.window.rootViewController) {
        UIViewController* presented = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
        orientations = [presented supportedInterfaceOrientations];
    }
    return orientations; 
}


回答2:

I would write a comment but I can't, so I'm posting this as an answer.

This was my scenario :

My app supports orientation changing only on certain views and I couldn't figure out how to do it just for the ones I wanted, then I landed to this question and saw mientus' answer(Thanks for this) then I went ahead and did what he suggested which was subclass UITabBarController and override these methods :

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    NSLog(@"AUTO ROTATE IN CUSTOM TAB BAR");
    // You do not need this method if you are not supporting earlier iOS Versions
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}


-(NSUInteger)supportedInterfaceOrientations{

    NSLog(@"supportedInterfaceOrientations IN CUSTOM TAB BAR");

    if (self.selectedViewController)
        return [self.selectedViewController supportedInterfaceOrientations];

    return UIInterfaceOrientationMaskPortrait;
}

-(BOOL)shouldAutorotate{

    NSLog(@"shouldAutorotate IN CUSTOM TAB BAR");
    return [self.selectedViewController shouldAutorotate];
}

then inside each view controller I would have the methods to indicate whether I wanted rotation or not. The methods in UITabBarController were getting called but not the ones in my viewcontroller therefore rotation was still happening where I didn't want to. Then I subclass UINavigationController and override the same methods only with this change on the supportedInterfaceOrientation one to look like this :

- (NSUInteger)supportedInterfaceOrientations{

NSLog(@"supportedInterfaceOrientations IN CUSTOM NAV BAR CALLING CURRENT VIEW CONTROLLER");
UIViewController* presented = [[self viewControllers] lastObject];
return [presented supportedInterfaceOrientations];

}

what this does basically, it gets the current view controller and then asks for the supported orientation and voila my methods in my viewcontroller get called and I can handle orientation where I want it.



回答3:

Is the view you want to rotate a subview of portrait-only view? Usually view rotation behaviour inherits from rootviewcontroller. Then if you return NO in shouldAutorotate in rootviewcontroller you stop rotation in every single underview.

I suggest to split your architecture this way:

rootViewController -> supportedInterfaceOrientations = Portrait & shouldAutorotate = YES NORotationViewControllers -> supportedInterfaceOrientations = Portrait & shouldAutorotate = YES rotationViewControllers -> supportedInterfaceOrientations = All & shouldAutorotate = YES

If you have not read this already, take a look at: Supporting Multiple Interface Orientations