23

Would like everything on the screen (UI) to be able to rotate from landscape left to right or vica versa.

How do I go about doing this? Is this private?

I know that

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {}

lets you say which orientations the UI can be, but is there a way to force only one at a time?

Cheers

3

10 Answers 10

24

In iOS [[UIDevice currentDevice] setDeviceOrientation:UIDeviceOrientationSomeOrientation] method is absent. But we can rotate a view with status bar, for this:

- (void)showAlbum {
    // check current orientation
    if ([[UIApplication sharedApplication] statusBarOrientation] != UIInterfaceOrientationLandscapeLeft) {
        // no, the orientation is wrong, we must rotate the UI
        self.navigationController.view.userInteractionEnabled = NO;
        [UIView beginAnimations:@"newAlbum" context:NULL];
        [UIView setAnimationDelegate:self];
        // when rotation is done, we can add new views, because UI orientation is OK
        [UIView setAnimationDidStopSelector:@selector(addAlbum)];
        // setup status bar
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft  animated:NO];
        // rotate main view, in this sample the view of navigation controller is the root view in main window
        [self.navigationController.view setTransform: CGAffineTransformMakeRotation(M_PI / 2)];
        // set size of view
        [self.navigationController.view setFrame:CGRectMake(0, 0, 748, 1024)];
        [UIView commitAnimations];
    } else {
        [self addAlbum];
    }

}
4
  • Thanks! All I needed was the UIView.transform property since the view I'm working on only needs to be in landscape orientation.
    – aiham
    Commented Sep 15, 2011 at 23:29
  • What about CoreMotion orientation? Does it change with status bar orientation?
    – Hari Honor
    Commented Jan 20, 2012 at 18:33
  • No,it doesnt. CoreMotion sends device-motion events this code cannt change device orientation it has changed just application screen orientation.
    – UIBuilder
    Commented Jan 23, 2012 at 15:08
  • I don't know how you can use an UIDeviceOrientation for setStatusBarOrientation. According to the class reference, you need to use an UIInterfaceOrientation. But perhaps you can explain your reasoning?
    – JohnK
    Commented Jun 20, 2013 at 23:29
18

I've had success with this:

 if (self.interfaceOrientation != UIInterfaceOrientationPortrait) {
    // http://stackoverflow.com/questions/181780/is-there-a-documented-way-to-set-the-iphone-orientation
    // http://openradar.appspot.com/radar?id=697
    // [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; // Using the following code to get around apple's static analysis...
    [[UIDevice currentDevice] performSelector:NSSelectorFromString(@"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
}
4
  • First thank you Chis!! But why did Apple make this method (setOrientation:) not avaliable for us? It's so easy and simple. But is it Apple proove also? Thx
    – NicTesla
    Commented Jul 2, 2012 at 13:26
  • 1
    By using this method any chance of rejection in apple approval process? Commented Oct 16, 2012 at 5:19
  • 3
    The above code will not compile under ARC. It does not appreciate the cast from NSInteger to id. You can, however, use NSInvocation instead. That said, it didn't work for me under iOS 6. Commented Jan 28, 2013 at 23:37
  • 4
    You can overcome the ARC issue with using: [[UIDevice currentDevice] performSelector:NSSelectorFromString(@"setOrientation:") withObject:(__bridge id)((void*)UIInterfaceOrientationPortrait)]; but it would not work under iOS6 anyway. Commented Jan 29, 2013 at 23:05
16

That method is called to determine whether your interface should automatically rotate to a given rotation (i.e letting UIKit do the hard work, rather than you doing it manually).

So if you wanted your app to only work in landscape you'd implement the body of that method with:

return UIInterfaceOrientationIsLandscape(interfaceOrientation);

If you wanted your UI to auto rotate to all orientations you could just return YES;

Is that what you were asking?

6
  • no, rather setting the UI orientation to different orientations by code at different times in the program. (so, for some context, it can mirror another device)
    – Sam Jarman
    Commented Dec 2, 2010 at 2:11
  • Oh OK, well in that case I would probably return YES for the orientations that your VC supports in that delegate method, and then try to force the orientation using: [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight]; I don't know if I've ever personally tried forcing it that way, but it might work...
    – tobyc
    Commented Dec 2, 2010 at 2:27
  • Not sure if this is your problem, but change your shouldAutorotateToInterfaceOrientation method to: return UIInterfaceOrientationIsLandscape(interfaceOrientation);
    – tobyc
    Commented Dec 2, 2010 at 2:55
  • And then maybe do what Justin Spahr-Summers says and modally present the view controller. That way you might not have to force the orientation using setOrientation. Doing crazy orientations can be a bitch...
    – tobyc
    Commented Dec 2, 2010 at 2:57
  • @half_brick : so I did what you told and it works nicely. My nib file is in landscape mode. and the specific view is always in landscape. however, if i rotate the hardware in landscape (the other way), the view controller doesn't rotate ... any help ?
    – Ahsan
    Commented Feb 1, 2012 at 18:11
5

If you present a modal view controller which implements -shouldAutorotateToInterfaceOrientation: to only support one orientation, the whole interface will automatically be forced into it. I don't think there's a way to programmatically change orientation otherwise.

3

Also this simple way works:

[[UIApplication sharedApplication] setStatusBarHidden:YES];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];

and back:

[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
1
  • This helped me fixing IPAD landscape launch issue: no touch event received at all. Calling setStatusBarHidden magically solves the problem. Commented Mar 14, 2013 at 15:42
3

In Swift to change the orientation to portrait:

UIDevice.currentDevice().setValue(UIInterfaceOrientation.Portrait.rawValue, forKey: "orientation")

See: https://stackoverflow.com/a/24259601

1
  • 1
    Thank you, I needed this answer!
    – sunlover3
    Commented Jun 7, 2017 at 12:22
2

This was addressed by: Guntis Treulands https://stackoverflow.com/a/10146270/894671

//-----------------------------------
// FORCE PORTRAIT CODE
//-----------------------------------
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
0
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
        objc_msgSend([UIDevice currentDevice], @selector(setOrientation:),    UIInterfaceOrientationLandscapeLeft );
    }
0

Even though this is not an idle solution, works well for me.

- (void)viewDidLoad
{
   self.view.transform = CGAffineTransformIdentity;
   self.view.transform = CGAffineTransformMakeRotation((M_PI * (90) / 180.0)); 
   self.view.bounds = CGRectMake(0.0, 0.0, 480, 320);
}
0

As suggested on a related thread shouldAutorotateToInterfaceOrientation is deprecated. Newer apps should leverage the following methods as described in Apple's UIViewController Class Reference until they themselves become deprecated:

  • shouldAutorotate,
  • preferredInterfaceOrientationForPresentation; and
  • attemptRotationToDeviceOrientation.

From what I understand it's best to use different View Controllers for views which need to lock into (i.e. have a preferred) orientation mode which differs from the last.

Not the answer you're looking for? Browse other questions tagged or ask your own question.