Как получить UI_USER_INTERFACE_IDIOM () для работы с iPhone OS SDK <3.2

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 OS), чтобы проверить свой универсальный код приложения iPhone, вы получите compiler errors, так как символы не определены в 3.1.3 или более ранних версиях , при компиляции для симулятора iPhone 3.1.3.

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

    Я делаю это, чтобы получить код для компиляции как в 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/

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

     - (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 sim. Затем он проверяет, отвечает ли class UIDevice на селектор. Если любой из них терпит неудачу, это не iPad.

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

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

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

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

     if (isIPhone) { ... } 

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

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

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

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

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

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

     - (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 } 

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

     #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 ) 

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

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

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

    Давайте будем гением компьютера.