Allow autorotation on just one view controller

2020-07-13 08:10发布

问题:

In my project I have allowed only portrait rotation, but for one ViewController I would like to enable also landscape. I'm presenting this ViewController as ModalViewController, I've tried using methods - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation or iOS 6 methods like -(NSUInteger) supportedInterfaceOrientations but nothing actually worked. The view didn't rotate although those methods got called.

After this I've tried to rotate it by myslef with listening to those notifications :

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didRotate:)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:nil];

but even though I was able to manually rotate the view in method didRotate: it's very messy and I can't rotate the StatusBar.

I would really like to use standard methods like shouldAutorotateToInterfaceOrientation, but I don't know how. Anyone?

回答1:

Add this in your app delegate.m

# pragma mark - Rotation

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if ([self.window.rootViewController isKindOfClass:[MVYSideMenuController class]]) {

        // Get topmost/visible view controller
        UIViewController *currentViewController = [self.window.rootViewController.childViewControllers lastObject];
        // Check whether it implements a dummy methods called canRotate
        if ([currentViewController respondsToSelector:@selector(canRotate)]) {
            // Unlock landscape view orientations for this view controller
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
    }

    // Only allow portrait (standard behaviour)
    return UIInterfaceOrientationMaskPortrait;
}
-(void)canRotate
{
}

and then add this method

-(void)canRotate
{
    // just define the method, no code required here
}

in every ViewController (.m files) where you want to provide rotation. You can also include here -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation method to react when the device rotates:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    switch (orientation) {
        case 1:
        case 2:
            //NSLog(@"portrait");
            break;

        case 3:
        case 4:
            //NSLog(@"landscape");
            break;
        default:
            //NSLog(@"other");
            break;
    }
}


回答2:

Subclass a navigation controller for your screen that requires rotation.

In the .m

// Older versions of iOS (deprecated) if supporting iOS < 5
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation    {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}

// iOS6
 - (BOOL)shouldAutorotate {
return YES;
 }

 // iOS6
 - (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}

This overrides the rotation methods set in the summary page for iOS 6.

In iOS 6 the view controllers only look to there parent or root controller for rotation methods



回答3:

can't you just call the shouldAutoRotateToInterfaceOrientation in the viewDidLoad and viewWillAppear like so:

[self shouldAutorotateToInterfaceOrientation];

that should call the method if its in your ViewController



回答4:

Implement is in all controller and Return on that interfaceOrientation which you need for a specific controller

For All

- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation{

 return YES;
}

For Landscape

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}

For Portrait

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