Как определить ориентацию устройства на iOS?

У меня вопрос о том, как определить ориентацию устройства на iOS. Мне не нужно получать уведомления об изменениях, только сама текущая ориентация. Это, кажется, довольно простой вопрос, но я не смог обвести вокруг него голову. Ниже приводится то, что я сделал до сих пор:

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

По моему мнению, это должно сработать. Я разрешаю устройству получать уведомления об ориентации устройства, а затем спрашивать, в какой ориентации он находится, но тогда он не работает, и я не знаю почему.

Ответ 1

Действительно старая нить, но никакого реального решения.

У меня была та же проблема, но выяснилось, что получение UIDeviceOrientation не всегда согласовано, поэтому вместо этого используйте это:

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

Ответ 2

если UIViewController:

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

если UIView:

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

UIDevice.h:

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

Обновление

добавьте этот код в xxx-Prefix.pch, тогда вы можете использовать его в любом месте:

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

использование:

if (isLandscape) { NSLog(@"Landscape"); }

Ответ 3

Для того, что вы ищете, сначала вам нужно получить уведомление, если изменилась ориентация! Вы можете установить эту вещь в viewDidLoad как

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

и всякий раз, когда ориентация вашего устройства изменилась OrientationDidChange Вызывается, где вы можете делать все, что хотите, в зависимости от ориентации

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

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

Ответ 4

Если вы хотите получить ориентацию устройства непосредственно с акселерометра, используйте [[UIDevice currentDevice] orientation]. Но если вам нужна текущая ориентация вашего приложения (ориентация интерфейса), используйте [[UIApplication sharedApplication] statusBarOrientation].

Ответ 5

UIViewController имеет свойство interfaceOrientation, доступ к которому можно получить, чтобы узнать текущую ориентацию контроллера вида.

Что касается вашего примера, это должно сработать. Когда вы говорите, что это не работает, что вы имеете в виду? Какие результаты он дает вам в сравнении с ожидаемыми?

Ответ 6

В Swift 3.0

чтобы получить ориентацию устройства.

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

чтобы получить ориентацию устройства из вашего приложения.

UIApplication.shared.statusBarOrientation

Ответ 7

Не удалось выполнить "UIDeviceOrientation" , потому что, когда ориентация UIViewcontroller привязана к определенной ориентации, вы не получаете соответствующую информацию с ориентацией устройства, поэтому правильная вещь - использовать "UIInterfaceOrientation" .

Вы можете получить ориентацию от UIViewController с помощью "self.interfaceOrientation" , но когда вы факторизуете наш код, вам может потребоваться выполнить такой тест вне контроллера представления (custom view, category...), так что вы все равно можете получить доступ к информации в любом месте вне контроллера, используя rootviewController:

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

Ответ 8

Есть ли способ достичь этого, если включена блокировка ориентации или нет, используя данные из CoreMotion. Это код:

#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");
                                }

                            }

}];

Ответ 9

Разблокировали ли вы аппаратную блокировку для ориентации устройства? Есть один на краю моего iPad 1.

Ответ 10

Вот некоторые переменные Swift, которые облегчают обнаружение:

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

Ответ 11

Мой текущий способ сделать это:

+ (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);
    }
}

Если по какой-то причине нет rootViewController, то все равно отказоустойчиво для statusBarOrientation...