3

I've see a dozen of possible related questions on SO, but no one seems duplicated:

how to force view to rotate to landscape in viewdidload?

force landscape ios 7

IOS - How to force the view to landscape

Force landscape for one view controller ios

iOS - Force Landscape Orientation

How to make app fully working correctly for autorotation in iOS 6?

My app is a tab-based application.

Currently when entering certain views, I can rotate my phone to landscape to let my view enter landscape.

Main Code:

// In app delegate
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if (_allowRotation == YES)  {
        return UIInterfaceOrientationMaskLandscape;
    }
    else {
        return UIInterfaceOrientationMaskPortrait;
    }
}

In views that I want to be landscape, I set allowRotation to YES.

But I want to force views to enter landscape.

In other word, when entering certain views, it automatically enters landscape, no need to rotate phone. Even user locks the screen as portrait. How to achieve this?

I'm using iOS 10.

Community
  • 1
  • 1
zhm
  • 3,513
  • 3
  • 34
  • 55
  • 1
    You give a lot of links but you do not seem to have understood them. There is only _one_ supported way to _force_ an orientation, and that is to use a presented view controller. – matt Feb 27 '17 at 17:43

4 Answers4

4

You have to override the onDidLoad or onDidAppear of the specific view that you want to move it to landscape, for example i added it to viewWillAppear and Disappear:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];
    self.navigationController.navigationBarHidden = NO;
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

-(void)viewWillDisappear:(BOOL)animated {
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    [super viewWillDisappear:animated];
}

so we the view appear the application move to landscape and when the move disappear it come again to portrait. and for the appDelegate you have to add this:

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
    if ([navigationController.viewControllers.lastObject isKindOfClass:[OpencvViewController class]])
    {
        return UIInterfaceOrientationMaskLandscape;
    }
    else
        return UIInterfaceOrientationMaskPortrait;
}
mzouink
  • 487
  • 1
  • 5
  • 13
  • Tried but no lucking. Does this suppose to work on iOS 10? – zhm Feb 27 '17 at 17:43
  • yes it's working ! try to deactivate orientation landscape from application params – mzouink Feb 28 '17 at 08:03
  • Couple notes. You have to use UIDeviceOrientation* and better to force switch the orientation _before_ your view controller is presented, that is, in the parent view controller. This allows switching it smoothly. – Cynichniy Bandera Mar 29 '20 at 11:49
1

Call [UIViewController attemptRotationToDeviceOrientation] when you need rotate orientation

Yours code will be something like that:

appDelegate.allowRotation = YES;
[UIViewController attemptRotationToDeviceOrientation];
Cy-4AH
  • 4,370
  • 2
  • 15
  • 22
  • Doesn't solve my problem. I want certain views automatically enter landscape **without** rotate device. – zhm Feb 27 '17 at 15:55
  • @MartinZhai, sorry. Lets clarify. For example: you want to display status bar always on one side, but rotate view with device? – Cy-4AH Feb 27 '17 at 15:58
  • I hide status/navigation/tab bar when enter these views (say, these views are fullscreen). What I want to do is like, programmatically trigger a landscape event to make device (or my view) enter landscape mode, without user rotate phone. – zhm Feb 27 '17 at 16:01
  • @MartinZhai Ok, you can trigger it as I said by calling `[UIViewController attemptRotationToDeviceOrientation]` but you will need change `supportedInterfaceOrientations` before that. – Cy-4AH Feb 27 '17 at 16:03
  • I tried, but seems not working. In my opinion, you method is to let view to be the same orientation with device, right? But in my problem, the device hasn't enter landscape yet. – zhm Feb 27 '17 at 16:07
  • @MartinZhai, have you enabled landscape orientations in Info.plist? – Cy-4AH Feb 27 '17 at 16:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136775/discussion-between-martin-zhai-and-cy-4ah). – zhm Feb 27 '17 at 16:14
1

Use below code in the specific view controller that you want to rotate in to landscape mode.

-(void)viewDidLayoutSubviews
{
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];

  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
 }
0

You need to use

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

for container view controller in window.rootViewController hierarchy or while presenting view controller over another one.

This enforces you controller to appear in landscape orientation.

The simplest example is assigning rootViewController to the main window. If you use UIInterfaceOrientationMaskLandscape in your view controller it appears in landscape from the very beginning.

If you try to pack your controller into navigation controller you'll need to subclass the latter to define UIInterfaceOrientationMaskLandscape in it because it is the container for your own view controller.

The same is valid for other containers (e.g. tabBarController or your own containers) which have parent-child link.

While presenting view controller you have also another method to fix orientation:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
malex
  • 9,874
  • 3
  • 56
  • 77
  • This need user to rotate his phone to trigger landscape, which I already did. I want to enter landscape without user rotate phone. – zhm Feb 27 '17 at 17:43
  • @MartinZhai, User doesn't need to rotate device. If one uses this for view controller which is the rootViewController for main window, the landscape mode will be from the beginning holding iPhone in portrait orientation. As for TabBarController being the rootViewController for window one should subclass TabBarController to work this way – malex Feb 27 '17 at 17:46