web-dev-qa-db-fra.com

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

Apple conseille d'utiliser le code suivant pour détecter si vous utilisez un iPad ou un 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]
}

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 aller complètement à l'encontre du but d'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 pouvez utiliser UI_USER_INTERFACE_IDIOM (), le résultat sera toujours d'indiquer un iPad. 

Si vous incluez ce code et le système d'exploitation cible 3.1.3 (le dernier système d'exploitation pour iPhone/iPod Touch) afin de tester le code de l'application universelle liée à votre iPhone, vous obtiendrez des erreurs de compilation, car les symboles ne sont pas définis en 3.1.3 ou antérieur. , lors de la compilation pour le simulateur iPhone 3.1.3.

S'il s'agit de l'approche recommandée par Apple pour la détection des périphériques à l'exécution, qu'est-ce que je fais de travers? Quelqu'un at-il réussi à utiliser cette approche pour la détection de périphérique?

32
drootang

Je fais ceci pour que le code soit compilé en 3.1.3 et 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
}

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

24
Sangraal

C'est ce que j'utilise:

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

Cela compile conditionnellement, vous pouvez donc toujours construire pour la sim 3.0. Il vérifie ensuite si la classe UIDevice répond au sélecteur. Si l'un ou l'autre échoue, ce n'est pas un iPad.

14
Ben Gottlieb

S'il s'agit de l'approche recommandée par Apple pour runtime détection de périphérique, qu'est-ce que je fais mal? Quelqu'un at-il réussi à utiliser cette approche de la détection de périphérique?

C'est la solution pour la détection runtime:

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

Après cela, vous pouvez facilement le tester n'importe où dans votre code:

if (isIPhone) { ... }

La différence entre ceci et l'utilisation de #if/#ifdef est qu'il s'agit de tests à l'exécution, alors que #if est à la compilation. 

Je pense que les tests d’exécution sont meilleurs, car vous pouvez en utiliser un exact pour n’importe quelle version de système d’exploitation dans ce cas. Si vous utilisez la vérification à la compilation, vous devrez générer différents exécutables pour différentes versions du système d'exploitation.

Si votre problème est lié aux erreurs de compilation, vous devez simplement compiler avec la dernière version du SDK (voir aussi Comment accéder au framework lié faible dans iOS? ). 

7
Mike Keskinov

Au lieu de tout ce qui est basé sur le compilateur, j'utilise:

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

Je crois que la réponse est simplement ne tentez pas d’exécuter le code sur iPhone simulator 3.1.3 ou une version antérieure. Toujours compiler avec un SDK 3.2. Le simulateur iPhone 3.2 vous fournira le simulateur iPad ou compilera pour iPhone Device 3.2 et installera l'application sur un téléphone pour la tester. 

Il n’existe aucun moyen de compiler avec le SDK 3.2 et d’utiliser un simulateur 3.1.3 ou antérieur.

5
drootang

Déclarer en utilisant cette 

#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif

puis utilisez check comme ci-dessous

#define DetailLabel_PosX (IS_IPAD ? 200 : 160)

Il y a aussi certains définir pour vérifier l'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 )
2
sinh99

UI_USER_INTERFACE_IDIOM () et UIUserInterfaceIdiomPad peuvent être utilisés sur iOS3.2 et les versions ultérieures, l'important étant la «version ascendante». Sûr. iOS3.2 est uniquement destiné à l'iPad, mais iOS4.0 et les versions ultérieures s'exécutent à la fois sur iPhone et sur iPad, de sorte que la vérification n'est pas aussi inutile que vous le pensez.

0
occulus

Cela semble aller complètement à l'encontre du but d'une telle fonction. Ils ne peut être compilé et exécuté sur iPhone OS 3.2 (iPhone OS 3.2 ne peut être exécuté Sur iPad). Donc, si vous pouvez utiliser UI_USER_INTERFACE_IDIOM (), le résultat sera toujours d'indiquer un iPad.

C'est complètement faux. Il peut être compilé sur le SDK de base 3.2, mais il peut également être exécuté sur n’importe quel système d’exploitation, si vous définissez correctement la cible de déploiement.

0
user102008