[ACCEPTED]-How Do I detect the orientation of the device on iOS?-uidevice

Accepted answer
Score: 120

Really old thread, but no real solution.

I 3 Had the same problem, but found out that 2 getting The UIDeviceOrientation isn't always 1 consistent, so instead use this:

UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

if(orientation == 0) //Default orientation 
    //UI is in Default (Portrait) -- this is really a just a failsafe. 
else if(orientation == UIInterfaceOrientationPortrait)
    //Do something if the orientation is in Portrait
else if(orientation == UIInterfaceOrientationLandscapeLeft)
    // Do something if Left
else if(orientation == UIInterfaceOrientationLandscapeRight)
    //Do something if right
Score: 76

if UIViewController:

if (UIDeviceOrientationIsLandscape(self.interfaceOrientation))
{
    // 
}

if UIView:

if (UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
{
    //
}

UIDevice.h:

#define UIDeviceOrientationIsPortrait(orientation)  ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown)
#define UIDeviceOrientationIsLandscape(orientation) ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight)

Updated:

add 2 this code to xxx-Prefix.pch then you can 1 use it anywhere:

// check device orientation
#define dDeviceOrientation [[UIDevice currentDevice] orientation]
#define isPortrait  UIDeviceOrientationIsPortrait(dDeviceOrientation)
#define isLandscape UIDeviceOrientationIsLandscape(dDeviceOrientation)
#define isFaceUp    dDeviceOrientation == UIDeviceOrientationFaceUp   ? YES : NO
#define isFaceDown  dDeviceOrientation == UIDeviceOrientationFaceDown ? YES : NO

usage:

if (isLandscape) { NSLog(@"Landscape"); }
Score: 22

For what You looking for first you have 5 to Get Notification if Orientation Changed! You 4 Can set This Thing in viewDidLoad like

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

and 3 whenever Orientation of your Device changed 2 OrientationDidChange Called where You can do whatever You Want 1 as Per Orientation

-(void)OrientationDidChange:(NSNotification*)notification
{
    UIDeviceOrientation Orientation=[[UIDevice currentDevice]orientation];

    if(Orientation==UIDeviceOrientationLandscapeLeft || Orientation==UIDeviceOrientationLandscapeRight)
    {
    }
    else if(Orientation==UIDeviceOrientationPortrait)
    {
    }
}
Score: 22

If you want to get device orientation directly from accelerometer 2 use [[UIDevice currentDevice] orientation]. But if you need current orientation 1 of your application(interface orientation) use [[UIApplication sharedApplication] statusBarOrientation].

Score: 9

UIViewController has an interfaceOrientation property that you can access to 5 find out the current orientation of a view 4 controller.

As for your example, that should 3 work. When you say it isn't working, what 2 do you mean? What results does it give you 1 versus what you expected?

Score: 8

In Swift 3.0

to get device orientation.

/* return current device orientation.
   This will return UIDeviceOrientationUnknown unless device orientation notifications are being generated. 
*/
UIDevice.current.orientation

to get device orientation from your app

UIApplication.shared.statusBarOrientation

0

Score: 4

Wasn't satisfied by "UIDeviceOrientation" because when a UIViewcontroller 10 orientation is fixed to a specific orientation 9 you don't get a pertinent information with 8 the device orientation, so the right thing 7 to do is using "UIInterfaceOrientation".

You can get the orientation 6 from the UIViewController with a "self.interfaceOrientation", but when 5 you are factorizing our code, you might 4 need to do this kind of test outside a view 3 controller, (custom view, a category…), so 2 you still can access the information anywhere 1 outside the controller by using the rootviewController:

if (UIInterfaceOrientationIsLandscape(view.window.rootViewController.interfaceOrientation)) {
}
Score: 2

There's a way to achieve this whether the 2 orientation lock is enabled or not by using data from CoreMotion. This is 1 the code:

#import <CoreMotion/CoreMotion.h> 

    CMMotionManager *cm=[[CMMotionManager alloc] init];
    cm.deviceMotionUpdateInterval=0.2f;
    [cm startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
                            withHandler:^(CMDeviceMotion *data, NSError *error) {

                            if(fabs(data.gravity.x)>fabs(data.gravity.y)){
                                    NSLog(@"LANSCAPE");
                                if(data.gravity.x>=0){
                                    NSLog(@"LEFT");
                                }
                                else{
                                    NSLog(@"RIGHT");
                                }

                        }
                        else{
                                NSLog(@"PORTRAIT");
                                if(data.gravity.y>=0){
                                    NSLog(@"DOWN");
                                }
                                else{

                                    NSLog(@"UP");
                                }

                            }

}];
Score: 1

Have you unlocked the hardware lock for 2 device orientation? There is one at the 1 edge of my iPad 1.

Score: 1

Here is some Swift variables to make detection 1 easier:

let LANDSCAPE_RIGHT: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight
let LANDSCAPE_LEFT: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft
let LANDSCAPE: Bool = LANDSCAPE_LEFT || LANDSCAPE_RIGHT
let PORTRAIT_NORMAL: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait
let PORTRAIT_REVERSE: Bool = UIDevice.currentDevice().orientation == UIDeviceOrientation.PortraitUpsideDown
let PORTRAIT: Bool = PORTRAIT_REVERSE || PORTRAIT_NORMAL
Score: 0

My current way of doing this:

+ (BOOL)isPortrait {
    let window = UIApplication.sharedApplication.delegate.window;
    if(window.rootViewController) {
        let orientation =
        window.rootViewController.interfaceOrientation;
        return UIInterfaceOrientationIsPortrait(orientation);
    } else {
        let orientation =
        UIApplication.sharedApplication.statusBarOrientation;
        return UIInterfaceOrientationIsPortrait(orientation);
    }
}

If there is 2 for some reason no rootViewController yet 1 fail safe to statusBarOrientation...

Score: 0

And the best reliable way in swift :

public extension UIScreen {

    public class var isPortrait: Bool {
        UIApplication.shared.delegate?.window??.rootViewController?.interfaceOrientation.isPortrait ??
                UIApplication.shared.statusBarOrientation.isPortrait
    }

    public class var isLandscape: Bool { !isPortrait }
}

0

Score: 0

This is my solution with Combine, which 4 is quite easy to use with SwiftUI or regular 3 Swift Object. A singleton object (static 2 instance) is better than the "environment" for 1 this kind of truly global object.

// Singleton object to keep the interface orientation (and any other global state)
class SceneContext: ObservableObject {
    @Published var interfaceOrientation = UIInterfaceOrientation.portrait
    static let shared = SceneContext()
}

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    ...
    func windowScene(_ windowScene: UIWindowScene, didUpdate previousCoordinateSpace: UICoordinateSpace, interfaceOrientation previousInterfaceOrientation: UIInterfaceOrientation, traitCollection previousTraitCollection: UITraitCollection) {
        SceneContext.shared.interfaceOrientation = windowScene.interfaceOrientation
    }
}

    // if you want to execute some code whenever the orientation changes in SwiftUI
    someView {
        ....
    }
    .onReceive(SceneContext.shared.$interfaceOrientation) { (orientation) in
        // do something with the new orientation
    }

    // if you want to execute some code whenever the orientation changes in a regular Swift object
    let pub = SceneContext.shared.$interfaceOrientation.sink(receiveValue: { (orientation) in
            // do something with the new orientation
            ...
        }) 

Score: 0

Use This Function.

    func deviceOrientation() -> String! {
    let device = UIDevice.current
    if device.isGeneratingDeviceOrientationNotifications {
            device.beginGeneratingDeviceOrientationNotifications()
            var deviceOrientation: String
            let deviceOrientationRaw = device.orientation.rawValue
            switch deviceOrientationRaw {
            case 1:
                deviceOrientation = "Portrait"
            case 2:
                deviceOrientation = "Upside Down"
            case 3:
                deviceOrientation = "Landscape Right"
            case 4:
                deviceOrientation = "Landscape Left"
            case 5:
                deviceOrientation = "Camera Facing Down"
            case 6:
                deviceOrientation = "Camera Facing Up"
            default:
                deviceOrientation = "Unknown"
            }
            return deviceOrientation
        } else {
            return nil
        }
    }

0

More Related questions