UIDeviceOrientationFaceUp - как различить портрет и пейзаж?

Я пытаюсь выяснить, находится ли устройство в портретном или альбомном режиме. Мой код работает довольно хорошо, если устройство не обращено вверх. Если он окажется лицом вверх (и ориентация == 5), он не будет различать портрет и пейзаж. Есть ли способ определить "ориентацию" с точки зрения пейзажа / портрета, если UIDeviceOrientation - FaceUp?

Мой код:

UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];

NSLog(@"orientation: %d", interfaceOrientation);

if (interfaceOrientation == UIDeviceOrientationIsLandscape(interfaceOrientation)) {
    NSLog(@"LANDSCAPE!!!");
}

if (interfaceOrientation == UIDeviceOrientationIsPortrait(interfaceOrientation)) {
    NSLog(@"PORTRAIT!!!");
}

2 ответа

Решение

Не надо путать UIDeviceOrientation а также UIInterfaceOrientationони разные, но связаны, как показано в их декларации

typedef enum {
   UIDeviceOrientationUnknown,
   UIDeviceOrientationPortrait,
   UIDeviceOrientationPortraitUpsideDown,
   UIDeviceOrientationLandscapeLeft,
   UIDeviceOrientationLandscapeRight,
   UIDeviceOrientationFaceUp,
   UIDeviceOrientationFaceDown
} UIDeviceOrientation;

typedef enum {
   UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
   UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
   UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
   UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;

UIDeviceOrientation говорит вам, какова ориентация устройства. UIInterfaceOrientation говорит вам, какова ориентация вашего интерфейса, и используется UIViewController, UIInterfaceOrientation будет явно либо портрет, либо пейзаж, тогда как UIDeviceOrientation может иметь неоднозначные значения (UIDeviceOrientationFaceUp, UIDeviceOrientationFaceDown, UIDeviceOrientationUnknown).

В любом случае вы не должны пытаться определить ориентацию UIViewController с [[UIDevice currentDevice] orientation], независимо от того, что ориентация устройства является UIViewController interfaceOrientation свойство может быть другим (например, если ваше приложение вообще не поворачивается в альбомную ориентацию) [[UIDevice currentDevice] orientation] может быть UIDeviceOrientationLandscapeLeft в то время как viewController.interfaceOrientation может быть UIInterfaceOrientationPortrait).

Обновление: Начиная с iOS 8.0, [UIViewController interfaceOrientation] устарела. Альтернатива, предлагаемая здесь, [[UIApplication sharedApplication] statusBarOrientation], Это также возвращает UIInterfaceOrientation,

Я создаю этот скелет кода для работы с желаемыми и нежелательными ориентациями устройств, в моем случае я хочу игнорировать UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp и UIDeviceOrientationFaceDown, кэшируя последнюю разрешенную ориентацию. Этот код касается устройств iPhone и iPad и может быть полезен для вас.

- (void)modXibFromRotation {

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    NSString *device = [[UIDevice currentDevice]localizedModel];
    UIInterfaceOrientation cachedOrientation = [self interfaceOrientation];

    if ([device isEqualToString:@"iPad"]) {

        if (orientation == UIDeviceOrientationUnknown || 
            orientation == UIDeviceOrientationFaceUp || 
            orientation == UIDeviceOrientationFaceDown) {

                orientation = (UIDeviceOrientation)cachedOrientation;
        }

        if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {

            /* Your code */
        }

        if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {

            /* Your code */     
        }
    }

    if ([device isEqualToString:@"iPhone"] || [device isEqualToString:@"iPod"]) {

        if (orientation == UIDeviceOrientationUnknown || 
        orientation == UIDeviceOrientationFaceUp || 
        orientation == UIDeviceOrientationFaceDown) {

            orientation = (UIDeviceOrientation)cachedOrientation;
        }

        if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {

             /* Your code */
        }

        if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {

            /* Your code */
        }
    }
}

Начиная с iOS13 используйте

UIInterfaceOrientation orientation;
if (@available(iOS 13.0, *)) {
    orientation = self.window.windowScene.interfaceOrientation;
} else {
    orientation = [[UIApplication sharedApplication] statusBarOrientation];
}
Другие вопросы по тегам