Подтвердить что ты не робот

Как получить 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, вы получите ошибки компилятора, так как символы не определены в 3.1. 3 или ранее, при компиляции для iPhone 3.1.3.

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

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

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

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

if (isIPhone) { ... }

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

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

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

Ответ 4

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

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

Ответ 5

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

- (BOOL)deviceIsAnIPad {
if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])
    //We can test if it 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
}

Ответ 6

Объявить с помощью этого

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

Ответ 7

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

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

Ответ 8

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