iOS: ориентация устройства при загрузке

Кажется, что когда мое приложение загружается, оно не знает своей текущей ориентации:

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
    NSLog(@"portrait");// only works after a rotation, not on loading app
}

После поворота устройства я получаю правильную ориентацию, но когда я загружаю приложение, не меняя ориентацию, кажется, что при использовании [[UIDevice currentDevice] orientation] текущая ориентация неизвестна.

Есть ли другой способ проверить это при первой загрузке приложения?


person Nic Hubbard    schedule 04.05.2011    source источник
comment
См. Также ориентацию iPhone.   -  person beryllium    schedule 20.02.2012


Ответы (16)


РЕДАКТИРОВАТЬ: Я неправильно прочитал ваш вопрос. Это позволит вам запустить приложение в определенных ориентациях. Только что понял, что вы пытаетесь выяснить ориентацию при запуске.

Есть способ проверить ориентацию строки состояния на UIApplication:

[[UIApplication sharedApplication] statusBarOrientation];

Оригинальный ответ

Попробуйте установить допустимую ориентацию устройства в файле plist:

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

Это будет означать, что ваше приложение поддерживает портретную ориентацию (кнопка «Домой» внизу), альбомная ориентация слева и альбомная ориентация справа.

Затем в ваших UIViewControllers вам нужно будет переопределить метод shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation), чтобы вернуть YES, когда приложение должно повернуться:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

     return interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

Это укажет UIViewController на автоматический поворот, если устройство находится в одной из поддерживаемых вами ориентаций. Если вы хотите также поддерживать перевернутую ориентацию (портрет с кнопкой «Домой» вверху), добавьте это в свой список и просто верните ДА из этого метода.

Сообщите нам, как это работает.

person groomsy    schedule 04.05.2011
comment
Да, проверка строки состояния - вот что помогло! - person Nic Hubbard; 05.05.2011
comment
Обратите внимание, что сообщение называется statusBarOrientation (а не statusbarOrientation с буквой «b» в нижнем регистре) - изменение отправлено на рассмотрение. - person penfold; 03.10.2011
comment
у меня не работает Я получаю портрет каждый раз. Пробую для Ipad и тестирую на симуляторе. Это зависит от оборудования. Будет ли работать на устройстве? - person Nilesh Tupe; 12.10.2011
comment
это не работает: устройство может быть в другой ориентации, чем строка состояния, если родительский вид не повернут в текущую ориентацию. - person cyrilchampier; 28.08.2012
comment
shouldAutorotateToInterfaceOrientation будет отличаться в зависимости от того, является ли корневой vc контроллером навигации или нет. - person ; 13.01.2013

Думаю, сработает:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;

Согласно ссылке UIDevice:
Цитата:
«Значение этого свойства всегда возвращает 0, если только уведомления об ориентации не были включены путем вызова beginGeneratingDeviceOrientationNotifications». Первоначально я предполагал, что это свойство всегда содержит текущую ориентацию , но не так, видимо. Я предполагаю, что включение уведомлений обрабатывается для нас за кулисами в других ситуациях, когда свойство ориентации обычно используется, поэтому не было очевидно, что это нужно делать вручную внутри делегата приложения.

person Iducool    schedule 04.05.2011
comment
Похоже, это не сработало, в итоге я использовал [UIApplication sharedApplication] .statusBarOrientation, который работает. - person Nic Hubbard; 04.05.2011

для тех, кто ищет ответ для Swift 3 или 4. просто добавьте этот код в блок viewDidLoad ().

let orientation = UIApplication.shared.statusBarOrientation
if orientation == .portrait {
      // portrait   
} else if orientation == .landscapeRight || orientation == .landscapeLeft{
      // landscape     
}

обновление для предупреждений об амортизации для IOS 13 и Swift 5.x используйте блок кода ниже.

 if #available(iOS 13.0, *) {
        let orientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
        if orientation == .portrait {
                     // portrait

               } else if orientation == .landscapeRight || orientation == .landscapeLeft{
                     // landscape
               }
    } else {
        // Fallback on earlier versions
        let orientation = UIApplication.shared.statusBarOrientation
        if orientation == .portrait {
                            // portrait

    } else if orientation == .landscapeRight || orientation == .landscapeLeft{
                               // landscape
    }
    }
person Bilal Şimşek    schedule 22.03.2018
comment
Я получил сообщение о том, что statusBarOrientation устарел. Может быть, вы сможете обновить свой ответ новыми значениями? - person Joseph Astrahan; 11.01.2020

Одна вещь, которую еще никто не затронул, - это то, что вы сохраняете UIDeviceOrientation типы в UIInterfaceOrientation переменной. Они разные, и их нельзя рассматривать как равные. Обратите внимание, что UIDeviceOrientationLeft равно UIInterfaceOrientationRight (поскольку интерфейс вращается в противоположную сторону по сравнению с устройством).

person Jeff Kelley    schedule 03.10.2011
comment
Да, устройство может быть ориентировано лицевой стороной вниз и лицевой стороной вверх. iOS 6 - это ступенька к решению проблем с ориентацией устройства / интерфейса. iOS ‹6 была глупо сложной и все еще сильно ломалась, начиная с iOS 6.0.1. Новый - (BOOL) shouldAutorotate никогда не вызывается, по крайней мере, в симуляторе. И shouldAutorotateToInterfaceOrientation преждевременно устарел. - person ; 13.01.2013

Вы можете сделать это, вставив следующее уведомление внутри

-(void)viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

затем поместите следующий метод в свой класс

-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
    {
         //Do your textField animation here
    }
}

Вышеупомянутый метод проверит ориентацию строки состояния ipad или iPhone, и в соответствии с ним вы сделаете свою анимацию в требуемой ориентации.

person Ahmed Hammad    schedule 13.11.2012

При загрузке ориентация устройства может быть .Unknown или .FaceUp. Чтобы понять, портретный или альбомный, я использую statusBarOrientation как резервную копию, например:

    var portraitOrientation = UIDevice.currentDevice().orientation == .Portrait

    if UIDevice.currentDevice().orientation == .Unknown || UIDevice.currentDevice().orientation == .FaceUp {
        portraitOrientation = UIApplication.sharedApplication().statusBarOrientation == .Portrait
    }

Таким образом, я могу заверить, что portraitOrientation всегда сообщает мне, находится ли устройство в портретном режиме, а если нет - в альбомном. Даже при первой загрузке приложения.

person Marijn    schedule 05.07.2016

Чтобы получить ориентацию из строки состояния, также важно, чтобы все ориентации были включены в файле plist.

person NicoRaf    schedule 06.03.2015

Swift 3 на основе кода @Marjin.

var portraitOrientation = UIDevice.current.orientation == .portrait

if UIDevice.current.orientation == .unknown || UIDevice.current.orientation == .faceUp {
     portraitOrientation = UIApplication.shared.statusBarOrientation == .portrait
}

if(portraitOrientation)
{
     // Portrait
}
else
{

}
person Nacho Badia    schedule 04.05.2017

Попробуйте акселерометр, чтобы получить его показания, UIAccelerometer, получите общий акселерометр, установите его делегата, получите показания, определите оттуда ориентацию.

person DavidN    schedule 04.05.2011
comment
Да, но у старых iPod touch нет акселерометра, так что в моем случае это не сработает. - person Nic Hubbard; 04.05.2011
comment
на самом деле даже у первого iPod Touch был акселерометр - person Matthias Bauch; 04.05.2011

Перепробовал все и никаких хороших результатов. Итак, что я сделал, поскольку у меня iPad, я оставил всю работу методам splitViewController, чтобы сделать barButton недействительным:

Для портрета:

- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc { NSlog(@"portrait");}

Для пейзажа:

- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem{ NSlog(@"landscape");}

это всегда работает под нагрузкой.

person user1008139    schedule 07.11.2011

проблема в том, что [UIDevice currentDevice]orientation] иногда неверно сообщает об ориентации устройства.

вместо этого используйте [[UIApplication sharedApplication]statusBarOrientation], который является UIInterfaceOrientation, поэтому для проверки вам нужно использовать UIInterfaceOrientationIsLandscape(orientation)

надеюсь это поможет.

person iksnae    schedule 09.05.2012
comment
При каких обстоятельствах неверно отображается ориентация устройства? Вы можете привести пример? - person Victor Engel; 18.05.2013

Я до сих пор использую этот рабочий фрагмент кода для iphone 4:

-(void)deviceOrientationDidChange:(NSNotification *)notification{

//Obtaining the current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];    

int value = 0;

if(orientation == UIDeviceOrientationPortrait)
{
    value = 0;

}else if(orientation == UIDeviceOrientationLandscapeLeft)
{
    value = 90;

}else if(orientation == UIDeviceOrientationLandscapeRight)
{

    value = -90;

}

CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(value));
[photoImageView setTransform:cgCTM];

}

person Rudolf Stepan    schedule 30.05.2012

Это настоящий ответ. Когда приложение запускается, его ориентация неизвестна. Он использует shouldAutorotateToInterfaceOrientation и supportedInterfaceOrientations, чтобы решить, какую ориентацию выбрать.

Посмотрите, как я запускаю пример приложения в симуляторе iPhone 5.0 и вращаю его, используя приведенный ниже код и «Поддерживаемые ориентации интерфейса» со всеми 4 возможными ориентациями:

20:44:08.218 RotationTestApp Supported orientation: Portrait
20:44:08.222 RotationTestApp Supported orientation: Portrait (upside-down)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the right)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the left)
20:44:08.226 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.237 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.239 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.240 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:09.817 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:09.833 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:11.030 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:11.040 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:12.599 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:12.609 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:13.301 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)

Я видел множество фрагментов кода, но ни один из них не работает в целом (iPad и iPhone, iOS 5.0+).

Вместо того, чтобы возиться с try-this-try-that, поместите следующее в корневой каталог vc:

#define ToNSString_BEGIN(T) \
NSString* T##ToNSString(T valueParameter) { \
switch (valueParameter) {

#define ToNSString_VALUE(value) \
case value: return @#value

#define ToNSString_END(T) \
} \
return @"(unknown)"; \
}

// NSString* UIInterfaceOrientationToNSString(UIInterfaceOrientation);
ToNSString_BEGIN(UIInterfaceOrientation);
ToNSString_VALUE(UIInterfaceOrientationPortrait);           // 1
ToNSString_VALUE(UIInterfaceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIInterfaceOrientationLandscapeLeft);      // 3
ToNSString_VALUE(UIInterfaceOrientationLandscapeRight);     // 4
ToNSString_END  (UIInterfaceOrientation);

// NSString* UIDeviceOrientationToNSString(UIDeviceOrientation);
ToNSString_BEGIN(UIDeviceOrientation);
ToNSString_VALUE(UIDeviceOrientationUnknown);               // 0
ToNSString_VALUE(UIDeviceOrientationPortrait);              // 1
ToNSString_VALUE(UIDeviceOrientationPortraitUpsideDown);    // 2
ToNSString_VALUE(UIDeviceOrientationLandscapeLeft);         // 3
ToNSString_VALUE(UIDeviceOrientationLandscapeRight);        // 4
ToNSString_VALUE(UIDeviceOrientationFaceUp);                // 5
ToNSString_VALUE(UIDeviceOrientationFaceDown);              // 6
ToNSString_END  (UIDeviceOrientation);



// Change this custom method to alter auto-rotation behavior on all supported iOS versions and platforms.
- (BOOL)allowAutoRotate:(UIInterfaceOrientation)interfaceOrientation
{
    NSUInteger interfaceOrientationAsMask = (1<<interfaceOrientation);
    return interfaceOrientationAsMask & [self supportedInterfaceOrientations];
}

// Reads from the project's-Info.plist
- (NSUInteger)supportedInterfaceOrientations
{
    static NSUInteger orientationsResult;

    if (!orientationsResult) {
        NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];

        for (id orientationString in supportedOrientations) {
            if ([orientationString isEqualToString:@"UIInterfaceOrientationPortrait"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortrait;
                NSLog(@"Supported orientation: Portrait");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortraitUpsideDown;
                NSLog(@"Supported orientation: Portrait (upside-down)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeRight"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeRight;
                NSLog(@"Supported orientation: Landscape (home button on the left)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeLeft;
                NSLog(@"Supported orientation: Landscape (home button on the right)");
            } else {
                NSLog(@"Unrecognized orientation '%@' in mainBundle plist, key UISupportedInterfaceOrientations", orientationString);
            }
        }
    }
   return orientationsResult;
}

// iOS 6+ (not yet used in 6.0.1)
- (BOOL)shouldAutorotate
{
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
    BOOL result = [self allowAutoRotate:interfaceOrientationFromDevice];
    NSString *currentDeviceOrientation = UIDeviceOrientationToNSString(interfaceOrientationFromDevice);
    NSLog(@"shouldAutorotate: %s (current orientation %@)", result ? "YES" : "NO", currentDeviceOrientation);
    return result;
}

// iOS 2.0 - 5.1 (iOS 6+ deprecated, 6.0.1 still works)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    NSString* orientationString;
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;

    if ((int)interfaceOrientation != (int)interfaceOrientationFromDevice) {
        orientationString = [NSString stringWithFormat:@"current device orientation: %@, interface orientation wants: %@",
                             UIDeviceOrientationToNSString(interfaceOrientationFromDevice),
                             UIInterfaceOrientationToNSString(interfaceOrientation)
                             ];
    } else {
        orientationString = [NSString stringWithFormat:@"device orientation: %@", UIDeviceOrientationToNSString(interfaceOrientationFromDevice)
                             ];
    }

    BOOL result = [self allowAutoRotate:interfaceOrientation];
    NSLog(@"shouldAutorotateToInterfaceOrientation: %s (%@)",
          result ? "YES" : "NO",
          orientationString);
    return result;
}

По-прежнему существует проблема с анимацией перехода, не использующей текущую ориентацию. Я предполагаю, что создание подкласса каждого VC и установка некоторой ориентации на делегат push / notify на pop было бы правильным решением.

Также важно:

shouldAutorotateToInterfaceOrientation не работает

tabBarController и navigationController в ландшафтном режиме, эпизод II

person Community    schedule 13.01.2013

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

UIInterfaceOrientation Ориентация = [UIApplication sharedApplication] .statusBarOrientation;

if(orientation == 0) {//Default orientation
    //UI is in Default (Portrait) -- this is really a just a failsafe.

    NSLog("for portrait");


}else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{

    NSLog("portrait");
}else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{

    NSLog("Landscap");
}
person jenish    schedule 24.09.2015

Попробуйте это [[UIApplication sharedApplication] statusBarOrientation];

или реализовать это в делегате приложения

(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}

оно работает

person Sabby    schedule 17.02.2016

Все выше опубликовали очень правильные ответы: но в качестве ОБНОВЛЕНИЯ: мнение Apple: вы должны использовать ориентацию UIStatusBar для чтения текущей ориентации устройства:

Один из способов проверить текущую ориентацию устройства - использовать значения типа int как таковые внутри метода viewDidLoad:

    int orientationType = [[UIDevice currentDevice] orientation];

где учтите следующее. . . - 1 = портрет (справа вверх) - 2 = перевернутый портрет - 3 = альбомный (справа) - 4 = альбомный (слева)

а затем вы можете использовать оператор IF для вызова метода после определения ориентации и т. д. и т. д .:

Надеюсь, это было немного полезно для кого-то

person Taskinul Haque    schedule 19.09.2013