28

I have developed an iOS App and tested it on iOS6 device. While testing, I realized that my App is not responding to Orientation changes as expected.

Here is my Code:

// Autorotation (iOS >= 6.0)
- (BOOL) shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationMaskPortrait;
}

Precisely, I want to know that what Methods are called on Orientation Changes in iOS.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Code Hunter
  • 10,075
  • 23
  • 72
  • 102
  • " my code is not working regarding orientation." means ? – Midhun MP Dec 12 '12 at 09:36
  • Actually I want to know which method called when I rotate my device..? – Code Hunter Dec 12 '12 at 09:39
  • It'll call the shouldAutorotate method and supported interface orientation method – Midhun MP Dec 12 '12 at 09:43
  • @MidhunMP This method deprecated in iOS 6... That's why. – Code Hunter Dec 12 '12 at 09:45
  • That's a misunderstanding, the `shouldAutoRotate` method is introduced instead of `shouldAutorotateToInterfaceOrientation`. And can be used in iOS5 and iOS 6 – Midhun MP Dec 12 '12 at 09:48
  • Please check http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html for more details – Midhun MP Dec 12 '12 at 09:52
  • Possible duplicate of [How to programmatically determine iPhone interface orientation?](http://stackoverflow.com/questions/634745/how-to-programmatically-determine-iphone-interface-orientation) – Suhaib Sep 19 '16 at 14:17

10 Answers10

61

You can try this, may help you out:

How to change the device orientation programmatically in iOS 6

OR

Objective-c:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]

Swift:

if UIDevice.current.orientation.isLandscape {
    // Landscape mode
} else {
    // Portrait mode
}
Shekhar Gupta
  • 6,206
  • 3
  • 30
  • 50
  • 12
    Note that `The value of |orientation| property always returns 0 unless orientation notifications have been enabled by calling beginGeneratingDeviceOrientationNotifications.` [Docs](http://developer.apple.com/library/ios/documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html#//apple_ref/doc/uid/TP40006902-CH3-SW3) – DanSkeel Aug 04 '13 at 15:27
  • Note that this is not the same as getting the ViewController orientation, since it may be in landscape but UIDevice.current.orientation.isLandscape may still return false. In my case UIDevice.current.orientation was .faceUp. – Giohji Jun 11 '21 at 18:42
36

You can try this, which solves your problem.

UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

Refer below link for App extension Get device current orientation (App Extension)

Community
  • 1
  • 1
Girish
  • 4,692
  • 4
  • 35
  • 55
  • Following methods are called when you rotate the device. shouldAutorotateToInterfaceOrientation, didRotateFromInterfaceOrientation & willRotateToInterfaceOrientation. – Girish Dec 12 '12 at 09:50
  • 2
    Really bad idea. Don't hook on that property. – DanSkeel Aug 04 '13 at 15:29
  • 2
    Some one can set this propery [`statusBarOrientation`](http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006728-CH3-SW10) and it will be no longer the same as real `interfaceOrientation`. `The status-bar orientation set by this method does not change if the device changes orientation.` – DanSkeel Aug 05 '13 at 10:37
  • 2
    @DanSkeel hows possible. We get the exact current orientation using this property. If we set the status bar orientation forcefully then its our responsibility to handled it carefully. – Girish Aug 05 '13 at 11:50
  • 1
    If you write some tool or framework you can't control all the code. So if you want to be sure that nobody did that, you should avoid it. IMHO. – DanSkeel Aug 05 '13 at 22:16
  • @DanSkeel According to my point of view, if we write some tool or framework then its our responsibility to handle it accordingly. – Girish Aug 06 '13 at 04:26
  • 2
    I mean you can't control the code of whole app that uses your framework. Because you're writing framework, not the app. And developer can set and you won't know about it. – DanSkeel Aug 06 '13 at 06:52
7

Maybe stupid but it is working (only in ViewController):

if (self.view.frame.size.width > self.view.frame.size.height) {
    NSLog(@"Hello Landscape");
}
Lau
  • 1,804
  • 1
  • 23
  • 49
6
  @property (nonatomic) UIDeviceOrientation m_CurrentOrientation ;

/* You need to declare these code in your ViewDidload or ViewWillAppear */

- (void)viewDidLoad

   {

   [super viewDidLoad];

   [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

   [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];
}

/* Now Our Device will give a notification whenever we change the orientation of our device,So you can control your code or program using the current orientation */

- (void)deviceOrientationDidChange:(NSNotification *)notification

 {

 //Obtaining the current device orientation

 /* Where self.m_CurrentOrientation is member variable in my class of type UIDeviceOrientation */

 self.m_CurrentOrientation = [[UIDevice currentDevice] orientation];

    // Do your Code using the current Orienation 

 }
Sanju
  • 1,148
  • 11
  • 26
Vicky
  • 1,095
  • 16
  • 15
  • how to put check for Portrait and Landscape by using self.m_CurrentOrientation ? – Sanju Feb 22 '16 at 12:40
  • if (UIDeviceOrientationIsLandscape(self.m_CurrentOrientation) { // code for landscape orientation } – Vicky Feb 22 '16 at 13:23
2

Follow the documentation on UIDevice.

You need to call

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

Then every time the orientation is changed you will receive a UIDeviceOrientationDidChangeNotification.

Boris Prohaska
  • 912
  • 6
  • 16
2

This tutorial gives a nice and simple overview of how to handle device rotation using UIDeviceOrientationDidChangeNotification. It should help you to understand how to use UIDeviceOrientationDidChangeNotification to be notified when the device orientation has changed.

Steph Sharp
  • 11,462
  • 5
  • 44
  • 81
1
UIDevice.current.orientation.isLandscape

The accepted answer reads the orientation of the device as above, which can be reported differently than the orientation of your view controller(s), particularly if your device is held in an almost horizontal position.

To get the orientation of your view controller specifically, you can use its interfaceOrientation property, which is deprecated since iOS 8.0 but still reports correctly.

Matt Mc
  • 8,882
  • 6
  • 53
  • 89
0

In your ViewController, you can use didRotateFromInterfaceOrientation: method to detect when the device has been rotated and then do whatever you need in every orientation.

Example:

#pragma mark - Rotation

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

        case 3:
        case 4:
            NSLog(@"landscape");
            // your code for landscape...
            break;
        default:
            NSLog(@"other");
            // your code for face down or face up...
            break;
    }
}
eduludi
  • 1,618
  • 21
  • 23
0

Swift 5 answer

Subscribe to notifications on orientations changes:

override func viewDidLoad() {
   super.viewDidLoad()
    
   NotificationCenter.default.addObserver(self, selector: #selector(orientationChangedFromNotification), name: UIDevice.orientationDidChangeNotification, object: nil)
}

Handle notification:

@objc func orientationChangedFromNotification() {
   self.updateUIForOrientation()
}

Handle orientation changes:

func updateUIForOrientation() {
   let orientation = UIDevice.current.orientation
   
   //TODO: Your logic
}

Note: This will tell you the orientation of the physical device. It is also possible to access the interface orientation of the app:

UIApplication.shared.delegate?.window?.windowScene?.interfaceOrientation
Mikkel Cortnum
  • 481
  • 4
  • 11
0

Note that [UIDevice currentDevice] orientation] and Application sharedApplication].statusBarOrientation are deprecated.

Using the deviceOrientationDidChange notification seems to be the best regular way to get the current orientation, BUT it doesn't provide the orientation when the app starts, this was a problem for me.

So, in the ViewDidLoad method, I read the screen size to detect the first orientation:

CGSize __screenSize = [UIScreen];

BUT the screen size is not reliable before a certain delay, so I found my solution by reading the screen size after a 1 second delay, like this:

[self performSelector:@selector( readScreenSize ) withObject:nil afterDelay:1];

To summarize, it works for me like this:

1/ By detecting the first orientation by reading the screen size after a short delay.

2/ By detecting orientation changes using the “deviceOrientationDidChange” notification.

Good luck.