2010-04-05 9 views
32

von Apple rät den folgenden Code verwenden, ob auf einem iPad oder iPhone/iPod Touch zu erkennen ausgeführt wird:Wie bekommt man UI_USER_INTERFACE_IDIOM() mit iPhone OS SDK zu arbeiten <3.2

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] 
} 

Das Problem ist, dass UI_USER_INTERFACE_IDIOM () und UIUserInterfaceIdiomPad sind NICHT in den SDKs vor 3.2 definiert. Dies scheint den Zweck einer solchen Funktion vollständig zu überwinden. Sie können nur auf iPhone OS 3.2 kompiliert und ausgeführt werden (iPhone OS 3.2 kann nur auf dem iPad ausgeführt werden). Wenn Sie also UI_USER_INTERFACE_IDIOM() verwenden können, wird immer ein iPad angezeigt.

Wenn Sie diesen Code verwenden und OS 3.1.3 (das neueste iPhone/iPod Touch-Betriebssystem) zum Testen Ihres iPhone-gebundenen universellen Anwendungscodes verwenden, erhalten Sie Compilerfehler, da die Symbole nicht in 3.1 definiert sind .3 oder früher, beim Kompilieren für iPhone Simulator 3.1.3.

Wenn dies der von Apple empfohlene Ansatz zur Laufzeitgeräteerkennung ist, was mache ich falsch? Ist es jemandem gelungen, diesen Ansatz zur Geräteerkennung zu nutzen? Diese

Antwort

14

ist das, was ich benutze:

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

Dies kompiliert bedingt, so dass Sie immer noch für 3,0 sim aufbauen können. Es überprüft dann, ob die UIDevice-Klasse auf den Selektor antwortet. Wenn beides nicht funktioniert, ist es kein iPad.

+0

Das ist, wenn Sie für 3.0 kompilieren möchten. Du solltest, wie drootang sagte, für 3.2 kompilieren und es auf einem 3.0-Gerät ausführen, weil 3.2 das ist, was du an den AppStore übermittelst. – conradev

+0

Ich stimme zu, aber es gibt keine Möglichkeit, im iPHONE Simulator (im Gegensatz zu iPad) zu testen, während für 3.2 gebaut. Wenn Sie beide Sims testen wollen, müssen Sie diese Art von Trickserei machen. –

5

Ich glaube, die Antwort ist einfach nicht versuchen, den Code auf dem iPhone Simulator 3.1.3 oder früher ausführen. Kompilieren Sie immer mit einem 3.2 SDK. Mit dem iPhone Simulator 3.2 erhalten Sie den iPad Simulator, oder kompilieren Sie für iPhone Device 3.2 und legen Sie die App auf ein Telefon, um es zu testen.

Es gibt keine Möglichkeit, gegen 3.2 SDK zu kompilieren und einen 3.1.3 oder früheren Simulator zu verwenden.

+5

ja da ist. Sie können für 3.2 SDK bauen und dann das aktuelle Ziel auf iPhone 3.1 ändern. Führen Sie dann entweder "Ausführen" oder "Debuggen" keine Neuerstellung durch. –

0

Dies scheint darauf hinzu vollständig den Zweck einer solchen Funktion zu besiegen. Sie können nur kompiliert und auf dem iPhone OS 3.2 ausgeführt werden (iPhone OS 3.2 kann nur auf iPad ausgeführt werden). Wenn Sie also UI_USER_INTERFACE_IDIOM() verwenden können, wird das Ergebnis immer ein iPad anzeigen.

Dies ist völlig inkorrekt. Es kann auf Base SDK von 3.2 kompiliert werden, aber es kann auf jedem Betriebssystem ausgeführt werden, wenn Sie das Bereitstellungsziel entsprechend festlegen.

0

UI_USER_INTERFACE_IDIOM() und UIUserInterfaceIdiomPad können auf iOS3.2 und höher verwendet werden, wobei der wichtigste Teil die "nach oben" ist. Sicher. iOS3.2 ist nur für das iPad, aber iOS4.0 und darüber hinaus läuft sowohl auf iPhones als auch auf iPads, also ist der Check nicht so sinnlos wie du denkst.

7

Wenn dies der empfohlene-by-Apple-Ansatz zur Runtime Geräteerkennung, was mache ich falsch?Hat jemand diesen Weg zur Geräteerkennung mit geschafft?

Dies ist Lösung für Laufzeit Erkennung:

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

Danach können Sie es leicht überall in Ihrem Code testen:

if (isIPhone) { ... } 

Der Unterschied zwischen diesem und mit # if/#ifdef ist, dass dies Laufzeittests ist, während #if Kompilierzeittests ist.

Ich denke, die Laufzeit-Tests sind besser, weil Sie in diesem Fall eine für jede Betriebssystemversion genau verwenden können. Wenn Sie die Kompilierungszeitprüfung verwenden, müssen Sie verschiedene ausführbare Dateien für verschiedene Betriebssystemversionen erstellen.

Wenn Ihr Problem Kompilierungsfehler ist, sollten Sie nur mit der letzten SDK-Version kompilieren (siehe auch How to access weak linked framework in iOS?).

5

Statt jedem Compiler basiert Sachen, die ich verwenden:

- (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 
} 
2

Deklarieren dieser

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

dann Scheck verwenden, wie unten

#define DetailLabel_PosX (IS_IPAD ? 200 : 160) 

Es gibt auch einige definieren für iphone Überprüfung 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) 
+0

obige Funktionen funktionieren nicht mehr – HarshIT