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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top