3

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

Eyal
  • 10,777
  • 18
  • 78
  • 130

4 Answers4

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.

Christian
  • 1,714
  • 8
  • 9
  • Yes I think you are right, for now it seems that there is no elegant solution to this problem, hopefully apple will support this kind of design in the future... – Eyal Jun 08 '12 at 09:45
  • the store view controller actually crashes in ios7, but it was fine previously – OMGPOP Jul 06 '13 at 01:44
  • I don't agree, whether it is a good user experience depends on features you provide to user, Skype is just a bad example, but not all. – evanchin Jul 21 '13 at 09:21
1

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!!

TheTiger
  • 13,264
  • 3
  • 57
  • 82
  • @Eyal - i have tried it in facebook API, my app is support lanscape mode while the facebook graph api is runs in Portrait mode so after finishing the work of facebook method i wrote the above code for changing the orientation and it works..... !! and in your question you asked for vie controller not for view – TheTiger Jun 07 '12 at 14:29
  • hey @Elay - try this [[UIDevice currentDevice] setOrientation:UIDeviceOrientationLandscapeRight]; it was work on old XCode but not sure it will work now. – TheTiger Jun 07 '12 at 14:51
1

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;
Nikunj
  • 987
  • 11
  • 25
1

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".

evanchin
  • 2,028
  • 1
  • 22
  • 25
  • If you think category is not a good design, you can subclass UINavigationController. a). Add some methods to change supported orientations and preferred orientation, call these method when you switch between view controllers. b). Delegate orientation related call to your view controller in your custom navigation controller. – evanchin Jul 21 '13 at 09:48