How Do I detect the orientation of the device on iOS?

IosObjective COrientationUidevice

Ios Problem Overview


I have a question on how to detect the device orientation on iOS. I don't need to receive change notifications, just the current orientation itself. This seems to be a rather simple question, but I haven't been able to wrap my head around it. Below is what I have done so far:

UIDevice *myDevice = [UIDevice currentDevice] ;
[myDevice beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation deviceOrientation = myDevice.orientation;
BOOL isCurrentlyLandscapeView = UIDeviceOrientationIsLandscape(deviceOrientation);
[myDevice endGeneratingDeviceOrientationNotifications];

In my mind this should work. I enable the device to receive device orientation notices, then ask for what orientation it is in, but then it is not working and I don't know why.

Ios Solutions


Solution 1 - Ios

Really old thread, but no real solution.

I Had the same problem, but found out that getting The UIDeviceOrientation isn't always 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

Solution 2 - Ios

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 this code to xxx-Prefix.pch then you can 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"); }

Solution 3 - Ios

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

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

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

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

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

Solution 4 - Ios

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

Solution 5 - Ios

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

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

Solution 6 - Ios

> 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

Solution 7 - Ios

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

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

if (UIInterfaceOrientationIsLandscape(view.window.rootViewController.interfaceOrientation)) {
}

Solution 8 - Ios

There's a way to achieve this whether the orientation lock is enabled or not by using data from CoreMotion. This is 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");
                                }

                            }

}];

Solution 9 - Ios

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

Solution 10 - Ios

Here is some Swift variables to make detection 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

Solution 11 - Ios

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 for some reason no rootViewController yet fail safe to statusBarOrientation...

Solution 12 - Ios

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

Solution 13 - Ios

This is my solution with Combine, which is quite easy to use with SwiftUI or regular Swift Object. A singleton object (static instance) is better than the "environment" for 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
            ...
        }) 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJusmanXView Question on Stackoverflow
Solution 1 - IosMoeView Answer on Stackoverflow
Solution 2 - IosTONy.WView Answer on Stackoverflow
Solution 3 - IosSaurabh PrajapatiView Answer on Stackoverflow
Solution 4 - IosrafalkittaView Answer on Stackoverflow
Solution 5 - IosJasarienView Answer on Stackoverflow
Solution 6 - IosAshok RView Answer on Stackoverflow
Solution 7 - IosNicolas LauquinView Answer on Stackoverflow
Solution 8 - IosFlySoFastView Answer on Stackoverflow
Solution 9 - IosMartin LütkeView Answer on Stackoverflow
Solution 10 - IosBeninho85View Answer on Stackoverflow
Solution 11 - IosRenetikView Answer on Stackoverflow
Solution 12 - IosRenetikView Answer on Stackoverflow
Solution 13 - IosSatoshi NakajimaView Answer on Stackoverflow