Is it possible to have different orientations for

2019-05-14 20:53发布

问题:

I want all view controllers to support only portrait mode, except one view controller lets call it "LandscapeSupportViewController" that should support also landscape mode.

The problem is when I'm in LandscapeSupportViewController in landscape mode and then push a new view controller that only support portrait mode, the pushed view controller will be in landscape mode also! How could I force it to be portrait?

I saw few apps that do it, take for example Skype iPhone app, the Messages tab is portrait only -> then if you press to enter the message itself you get a view controller that support landscape also because it make sense to enable landscape mode when user is chatting -> then if you press to view the persons profile, a new view controller will be pushed but in portrait! the same happen if you go back, you will forced to return to portrait even if you came from landscape...

Thanks

回答1:

I'd had students try to accomplish exactly what you are trying to accomplish, and after much research, the general consensus is: this is a bad idea and requires a lot of (App Store legal) hacks to accomplish, and still doesn't turn out too pretty (status bar, for example, screws up). You'll notice in the Skype app that when you go into the IM section, rotate to landscape, and hit back, the UI "snaps", or sort of gets instantly reloaded.

This is not a good user experience, and I'd recommend rethinking your design to be more in line with what Apple recommends.



回答2:

If i got you correctly you want to change device orientation in some conditions.

[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];

set your own orientation using above line, just put this lines inside the if condition. condition is depends on you.

Thank you!!



回答3:

Write this lines before you push viewController which supported only portrait From landscapeViewController

[appdel.navigationController.view removeFromSuperview];// This navcontroller used with rootviewcontroller
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
[ [UIApplication sharedApplication].self.delegate.window addSubview:appdel.navigationController.view];
self.navigationController.navigationBar.hidden=NO;


回答4:

Here is a solution. You can add a category for UINavigationController which manages the view controller orientation. See code below:

@interface UINavigationController (MyViewOrientations)
@end

@implemetation UINavigationController (MyViewOrientations)

- (BOOL)supportLandscapeModeForViewController:(UIViewController *)controller {
    return [controller isKindOfClass:[LandscapeSupportViewController class]]
}

- (NSUInteger)supportedInterfaceOrientation {
    UIViewController *controller = [self visibleViewController];
    NSUInteger orientationMasks = UIInterfaceOrientationMaskPortrait
    if([self supportLandscapeModeForViewController:controller]) {
        orientationMasks |= UIInterfaceOrientationMaskLandscapeLeft;
        orientationMasks |= UIInterfaceOrientationMaskLandscapeRight;
    }
    return orientationMasks;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    UIViewController *controller = [self visibleViewController];
    if([self supportLandscapeModeForViewController:controller]) {
        return UIInterfaceOrientationLandscapeLeft; // Your call
    }
    else {
        return UIInterfaceOrientationPortrait;
    }
}

- (BOOL)shouldAutorotate {
    UIViewController *controller = [self visibleViewController];
    return [self supportLandscapeModeForViewController:controller];
}
@end

If the situation is more complex, different views support different orientations. You can override "supportedInterfaceOrientation", "preferredInterfaceOrientationForPresentation", "shouldAutorotate" in your view controllers, and delegate calls from UINavigationController category code with "visibleViewController".