Como fazer UI_USER_INTERFACE_IDIOM() funcionar com iPhone OS SDK <3.2
-
24-09-2019 - |
Pergunta
A Apple recomenda usar o seguinte código para detectar se está sendo executado em um iPad ou 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]
}
O problema é que UI_USER_INTERFACE_IDIOM() e UIUserInterfaceIdiomPad NÃO estão definidos nos SDKs anteriores à versão 3.2.Isto parece anular completamente o propósito de tal função.Eles só podem ser compilados e executados no iPhone OS 3.2 (o iPhone OS 3.2 só pode ser executado no iPad).Então se você puder usar UI_USER_INTERFACE_IDIOM(), o resultado sempre será indicar um iPad.
Se você incluir este código e direcionar o OS 3.1.3 (o sistema operacional mais recente do iPhone/iPod Touch) para testar o código do aplicativo universal vinculado ao iPhone, você receberá erros do compilador, pois os símbolos não estão definidos no 3.1.3 ou anterior , ao compilar para o simulador de iPhone 3.1.3.
Se esta é a abordagem recomendada pela Apple para detecção de dispositivos em tempo de execução, o que estou fazendo de errado?Alguém conseguiu usar essa abordagem para detecção de dispositivos?
Solução
Eu faço isso para obter o código para compilar em 3.1.3 e 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
}
Eu também escrevi um rápido post sobre isso aqui:http://www.programbles.com/2010/04/03/compiling-condition-code-in-universal-iphone-ipad-applications/
Outras dicas
Isso é o que eu uso:
- (BOOL) amIAnIPad {
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
if ([[UIDevice currentDevice] respondsToSelector: @selector(userInterfaceIdiom)])
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
#endif
return NO;
}
Isso compila condicionalmente, para que você ainda possa construir para o SIM 3.0. Em seguida, ele verifica se a classe Uidevice responde ao seletor. Se um desses falhar, não é um iPad.
Se este é o recomendado-por-Apple abordagem tempo de execução dispositivo de detecção, o que estou fazendo de errado?Alguém já conseguiu usar esta abordagem para detecção de dispositivos?
Esta é a solução para tempo de execução detecção:
#define isIPhone (![[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
Depois que você pode facilmente testá-lo em qualquer lugar no seu código:
if (isIPhone) { ... }
A diferença entre este e usando #se / #ifdef é que este é o tempo de execução do teste, enquanto #se é tempo de compilação de testes.
Eu acho que o tempo de execução do teste é melhor, porque você pode usar um exactable para qualquer versão do SO neste caso.Se você usar o tempo de compilação de seleção, você vai precisar para produzir executáveis diferentes para diferentes versões do SO.
Se o seu problema é que erros de tempo de compilação, você só deve compilar contra a última versão do SDK (ver também Como acessar fraco vinculada quadro no iOS?).
Eu acredito que a resposta é simplesmente não tente executar o código no iPhone simulador 3.1.3 ou anterior. Sempre compile com um 3,2 SDK. O iPhone Simulator 3.2 receberá o simulador do iPad ou compilará o iPhone Device 3.2 e colocará o aplicativo em um telefone para testá -lo.
Não há como compilar o 3.2 SDK e usar um simulador 3.1.3 ou anterior.
Em vez de qualquer material baseado em compilador que eu uso:
- (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
}
Declarar usando este
#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif
em seguida, use verificar como abaixo
#define DetailLabel_PosX (IS_IPAD ? 200 : 160)
Existem também alguns definir para a verificação do 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 )
Isso parece derrotar completamente o objetivo de tal função. Eles só podem ser compilados e executados no iPhone OS 3.2 (o iPhone OS 3.2 só pode ser executado no iPad). Portanto, se você puder usar o UI_USER_INTERFACE_IDIOM (), o resultado sempre será indicar um iPad.
Isso está completamente incorreto. Pode ser compilado na base SDK de 3,2, mas pode ser corre Em qualquer sistema operacional, se você definir a meta de implantação adequadamente.
UI_USER_INTERFACE_IDIOM() e UIUserInterfaceIdiomPad podem ser usados no iOS3.2 e superior, sendo a parte importante o 'acima'.Claro.iOS3.2 é apenas para iPad, mas iOS4.0 e posteriores rodam em iPhones e iPads, então a verificação não é tão inútil quanto você pensa.