Как заставить UI_USER_INTERFACE_IDIOM () работать с iPhone OS SDK <3.2 - PullRequest
32 голосов
/ 05 апреля 2010

Apple рекомендует использовать следующий код, чтобы определить, работает ли он на iPad или iPhone / iPod Touch:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  // The device is an iPad running iPhone 3.2 or later.
  // [for example, load appropriate iPad nib file]
}
else {
  // The device is an iPhone or iPod touch.
  // [for example, load appropriate iPhone nib file]
}

Проблема в том, что UI_USER_INTERFACE_IDIOM () и UIUserInterfaceIdiomPad НЕ определены в SDK до 3.2. Это, кажется, полностью разрушает цель такой функции. Их можно скомпилировать и запустить только на iPhone OS 3.2 (iPhone OS 3.2 может работать только на iPad). Поэтому, если вы можете использовать UI_USER_INTERFACE_IDIOM (), результат всегда будет указывать на iPad.

Если вы включите этот код и целевую ОС 3.1.3 (самую последнюю ОС iPhone / iPod Touch) для тестирования кода универсального приложения для iPhone, вы получите ошибки компилятора, поскольку символы не определены в 3.1. 3 или ранее, при компиляции для симулятора iPhone 3.1.3.

Если это рекомендуемый Apple подход к обнаружению устройств во время выполнения, что я делаю не так? Кому-нибудь удалось использовать этот подход к обнаружению устройств?

Ответы [ 8 ]

24 голосов
/ 09 апреля 2010

Я делаю это, чтобы получить код для компиляции в 3.1.3 и 3.2:

BOOL iPad = NO;
#ifdef UI_USER_INTERFACE_IDIOM
iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#endif
if (iPad) {
// iPad specific code here
} else {
// iPhone/iPod specific code here
}

Я также написал краткий пост в блоге об этом здесь: http://www.programbles.com/2010/04/03/compiling-conditional-code-in-universal-iphone-ipad-applications/

14 голосов
/ 05 апреля 2010

Вот что я использую:

- (BOOL) amIAnIPad {
    #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
        if ([[UIDevice currentDevice] respondsToSelector: @selector(userInterfaceIdiom)])
            return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
    #endif
    return NO;
}

Это условно компилируется, так что вы все равно можете собрать для 3.0 сим. Затем он проверяет, отвечает ли класс UIDevice селектору. Если что-то из этого не получится, это не iPad.

7 голосов
/ 05 января 2012

Если это рекомендуемый Apple подход к время выполнения обнаружение устройства, что я делаю не так? Кто-нибудь смог использовать это подход к устройству обнаружения?

Это решение для времени выполнения обнаружения:

#define isIPhone (![[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)

После этого вы можете легко протестировать его в любом месте кода:

if (isIPhone) { ... }

Разница между этим и использованием #if / #ifdef заключается в том, что это тестирование во время выполнения, а #if - тестирование во время компиляции.

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

Если ваша проблема связана с ошибками во время компиляции, вам следует просто выполнить компиляцию с последней версией SDK (см. Также Как получить доступ к слабосвязанной среде в iOS? ).

5 голосов
/ 17 апреля 2012

Вместо любого материала на основе компилятора я использую:

- (BOOL)deviceIsAnIPad {
if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])
    //We can test if it's an iPad. Running iOS3.2+
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
        return YES; //is an iPad
    else 
        return NO; //is an iPhone
else 
    return NO; //does not respond to selector, therefore must be < iOS3.2, therefore is an iPhone
}
5 голосов
/ 05 апреля 2010

Я считаю, что ответ просто не пытайтесь запустить код на iPhone simulator 3.1.3 или более ранней версии. Всегда компилируйте с 3.2 SDK. Симулятор iPhone 3.2 предоставит вам симулятор iPad или скомпилирует для iPhone Device 3.2 и поместит приложение на телефон, чтобы протестировать его.

Невозможно скомпилировать SDK 3.2 и использовать симулятор 3.1.3 или более ранней версии.

2 голосов
/ 26 июля 2012

Объявите, используя это

#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif

, затем используйте проверку как показано ниже

#define DetailLabel_PosX (IS_IPAD ? 200 : 160)

Есть также некоторые определения для проверки iphone 5

#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
#define IOS_OLDER_THAN_6 ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_6 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0 )
0 голосов
/ 29 мая 2011

UI_USER_INTERFACE_IDIOM () и UIUserInterfaceIdiomPad можно использовать на iOS3.2 и выше, важной частью является «вверх». Конечно. iOS3.2 предназначена только для iPad, но iOS4.0 и более поздние версии работают как на iPhone, так и на iPad, поэтому проверка не так бессмысленна, как вы думаете.

0 голосов
/ 12 марта 2011

Кажется, это полностью противоречит цели такой функции. Oни можно только скомпилировать и запустить на iPhone OS 3.2 (iPhone OS 3.2 может быть запущена только на iPad). Так что, если вы можете использовать UI_USER_INTERFACE_IDIOM (), результат всегда будет указывать на iPad.

Это совершенно неверно. Это может быть скомпилированный на Base SDK 3.2, но это может быть run на любой ОС, если вы правильно установите цель развертывания.

...