Get device current orientation (App Extension)

后端 未结 10 1466
执笔经年
执笔经年 2020-12-09 10:02

How to get device current orientation in an App Extension, I have tried below two methods but no success.

  1. It always return UIDeviceOrientationUnknown

    <
相关标签:
10条回答
  • 2020-12-09 10:43

    I got an idea!

    extension UIScreen {
    
        var orientation: UIInterfaceOrientation {
            let point = coordinateSpace.convertPoint(CGPointZero, toCoordinateSpace: fixedCoordinateSpace)
            if point == CGPointZero {
                return .Portrait
            } else if point.x != 0 && point.y != 0 {
                return .PortraitUpsideDown
            } else if point.x == 0 && point.y != 0 {
                return .LandscapeLeft
            } else if point.x != 0 && point.y == 0 {
                return .LandscapeRight
            } else {
                return .Unknown
            }
        }
    
    }
    

    EDIT: On Swift 4 you can do:

    extension UIScreen {
        var orientation: UIInterfaceOrientation {
            let point = coordinateSpace.convert(CGPoint.zero, to: fixedCoordinateSpace)
            switch (point.x, point.y) {
            case (0, 0):
                return .portrait
            case let (x, y) where x != 0 && y != 0:
                return .portraitUpsideDown
            case let (0, y) where y != 0:
                return .landscapeLeft
            case let (x, 0) where x != 0:
                return .landscapeRight
            default:
                return .unknown
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-09 10:43

    You could take a look at this library and its forks. It uses CoreMotion to detect the device orientation so it may work on App Extension's restricted environment.

    0 讨论(0)
  • 2020-12-09 10:44

    The observer method will get called if you add this before: [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

    Edit: I use UIApplicationDidChangeStatusBarOrientationNotification for the observer

    And in my method I check:

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; BOOL isPortrait = UIDeviceOrientationIsPortrait(orientation);

    Edit 2- Xcode 6.2 - iOS 7 & 8

    It seems that if you want to use this on both iOS 7 & 8, the code above will give you wrong result on iOS 7.

    So I use something else because on iOS 7 the mainScreen's bounds will never change, but on iOS 8 will change if the orientation changes.

    I've got 3 macros that will give me the right size of the screen's width & height regardless of the iOS version:

    #define IOS_VERSION_OLDER_THAN_8 ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
    
    #define SCREEN_WIDTH_CALCULATED (IOS_VERSION_OLDER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height) : [[UIScreen mainScreen] bounds].size.width)
    
    #define SCREEN_HEIGHT_CALCULATED (IOS_VERSION_OLDER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width) : [[UIScreen mainScreen] bounds].size.height)
    

    Then, when the notification is fired, i check the orientation like this:

    BOOL isPortrait = SCREEN_WIDTH_CALCULATED < SCREEN_HEIGHT_CALCULATED;
    

    This will work on iOS 7 & iOS 8, but i didn't check for older versions of Xcode, only 6.2

    This will return only if the device is on portrait or landscape, not all the 4 orientation types

    0 讨论(0)
  • 2020-12-09 10:47

    Use CoreMotion framework can get the device orientation.

    func startMonitorDeviceOrientation() {
        if motionManager.isDeviceMotionAvailable {
            motionManager.deviceMotionUpdateInterval = 1.0
            let queue = OperationQueue()
    
            motionManager.startDeviceMotionUpdates(to: queue) { (deviceMotion, error) in
                guard let x = deviceMotion?.gravity.x,
                let y = deviceMotion?.gravity.y
                else {
                    return
                }
    
                if fabs(y) >= fabs(x) {
                    if y >= 0 {
                        // UIDeviceOrientationPortraitUpsideDown;
                        print("device orientation UIDeviceOrientationPortraitUpsideDown")
                    } else {
                        // UIDeviceOrientationPortrait;
                        print("device orientation UIDeviceOrientationPortrait")
                    }
                } else {
                    if x >= 0 {
                        // UIDeviceOrientationLandscapeRight;
                        print("device orientation UIDeviceOrientationLandscapeRight")
                    } else {
                        // UIDeviceOrientationLandscapeLeft;
                        print("device orientation UIDeviceOrientationLandscapeLeft")
                    }
                }
            }
        } else {
            print("Device motion is not avaliable")
        }
    }
    
    0 讨论(0)
  • 2020-12-09 10:49

    I found a way where we can calculate our device orientation like this way in (App Extension)

    - (void)viewDidLayoutSubviews
    {
       if(self.view.frame.size.width > self.view.frame.size.height)
          NSLog(@"Landscape");
       else
          NSLog(@"Portrait");
    }
    

    It gives me right orientation but still not get as device is LandscapeLeft or LandscapeRight as well as Portrait or PortraitUpsideDown.

    Still need help.

    0 讨论(0)
  • 2020-12-09 10:50

    This code won't give you the exact UIDeviceOrientation but you'll be able to know if it's in portrait or landscape mode

    BOOL isLandScape = !(self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height)));
    
    0 讨论(0)
提交回复
热议问题