32 votes

Comment obtenir UI_USER_INTERFACE_IDIOM() pour fonctionner avec iPhone OS SDK < 3.2

Apple conseille d'utiliser le code suivant pour détecter s'il s'agit d'un iPad ou d'un iPhone / iPod Touch :

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  // Le périphérique est un iPad fonctionnant sous iPhone 3.2 ou ultérieur.
  // [par exemple, chargez le fichier nib iPad approprié]
}
else {
  // Le périphérique est un iPhone ou iPod touch.
  // [par exemple, chargez le fichier nib iPhone approprié]
}

Le problème est que UI_USER_INTERFACE_IDIOM() et UIUserInterfaceIdiomPad ne sont PAS définis dans les SDK antérieurs à 3.2. Cela semble totalement vain pour une telle fonction. Ils ne peuvent être compilés et exécutés que sur iPhone OS 3.2 (iPhone OS 3.2 ne peut être exécuté que sur iPad). Donc, si vous utilisez UI_USER_INTERFACE_IDIOM(), le résultat sera toujours d'indiquer un iPad.

Si vous incluez ce code et ciblez OS 3.1.3 (le système d'exploitation le plus récent d'iPhone/iPod Touch) afin de tester votre code d'application universelle pour iPhone, vous obtiendrez des erreurs de compilation car les symboles ne sont pas définis dans 3.1.3 ou antérieur, lors de la compilation pour l'émulateur iPhone 3.1.3.

Si c'est l'approche recommandée par Apple pour la détection des périphériques en temps réel, que fais-je de mal? Quelqu'un a-t-il réussi à utiliser cette approche pour la détection des périphériques?

24voto

Sangraal Points 386

Je fais cela pour que le code compile à la fois en 3.1.3 et en 3.2 :

BOOL iPad = NO;
#ifdef UI_USER_INTERFACE_IDIOM
iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#endif
if (iPad) {
// Code spécifique à l'iPad ici
} else {
// Code spécifique à l'iPhone/iPod ici
}

J'ai également écrit un court article de blog à ce sujet ici : http://www.programbles.com/2010/04/03/compiling-conditional-code-in-universal-iphone-ipad-applications/

14voto

Ben Gottlieb Points 59900

C'est ce que j'utilise:

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

Cela compile de manière conditionnelle, donc vous pouvez toujours construire pour la simulation 3.0. Ensuite, il vérifie si la classe UIDevice répond au sélecteur. Si l'une de ces conditions échoue, ce n'est pas un iPad.

7voto

Mike Keskinov Points 2890

Si cela est l'approche recommandée par Apple pour la détection des appareils en temps d'exécution, qu'est-ce que je fais de mal? Est-ce que quelqu'un a réussi en utilisant cette approche de détection des appareils?

Voici la solution pour la détection en temps d'exécution:

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

Ensuite, vous pouvez le tester facilement n'importe où dans votre code:

if (isIPhone) { ... }

La différence entre ceci et l'utilisation de #if / #ifdef est que ceci est un test en temps d'exécution, tandis que #if est un test en temps de compilation.

Je pense que le test en temps d'exécution est meilleur, car vous pouvez utiliser un exécutable pour n'importe quelle version du système d'exploitation dans ce cas. Si vous utilisez une vérification en temps de compilation, vous devrez produire des exécutables différents pour différentes versions du système d'exploitation.

Si votre problème concerne les erreurs de compilation, vous devriez simplement compiler contre la dernière version du SDK (voir aussi Comment accéder à un framework lié faiblement sur iOS?).

5voto

drootang Points 471

Je crois que la réponse est simplement de ne pas essayer d'exécuter le code sur l'iPhone simulateur 3.1.3 ou antérieur. Compilez toujours avec un SDK 3.2. Le simulateur d'iPhone 3.2 vous donnera le simulateur d'iPad, ou compilez pour l'appareil iPhone 3.2 et mettez l'application sur un téléphone pour la tester.

Il n'y a aucun moyen de compiler contre le SDK 3.2 et d'utiliser un simulateur 3.1.3 ou antérieur.

5voto

MattyG Points 5126

Au lieu de toutes les choses basées sur le compilateur j'utilise:

- (BOOL)deviceIsAnIPad {
if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])
    //Nous pouvons tester s'il s'agit d'un iPad. Fonctionne sous iOS3.2+
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
        return YES; //est un iPad
    else 
        return NO; //est un iPhone
else 
    return NO; //ne répond pas au sélecteur, donc doit être < iOS3.2, donc est un iPhone
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X