2010-04-05 7 views
32

di Apple consiglia utilizzando il seguente codice per rilevare se in esecuzione su un iPad o iPhone/iPod Touch:Come si arriva UI_USER_INTERFACE_IDIOM() per lavorare con iPhone OS SDK <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] 
} 

Il problema è che UI_USER_INTERFACE_IDIOM () e UIUserInterfaceIdiomPad NON sono definiti negli SDK precedenti alla 3.2. Questo sembra vanificare completamente lo scopo di tale funzione. Possono essere compilati ed eseguiti solo su iPhone OS 3.2 (iPhone OS 3.2 può essere eseguito solo su iPad). Quindi se puoi utilizzare UI_USER_INTERFACE_IDIOM(), il risultato sarà sempre quello di indicare un iPad.

Se si include questo codice e il sistema operativo di destinazione 3.1.3 (il più recente sistema operativo iPhone/iPod Touch) per testare il proprio codice universale associato a iPhone, si otterranno errori del compilatore poiché i simboli non sono definiti in 3.1 .3 o precedenti, durante la compilazione per il simulatore iPhone 3.1.3.

Se questo è l'approccio consigliato da Apple per il rilevamento del dispositivo di runtime, cosa sto facendo male? Qualcuno è riuscito a utilizzare questo approccio per il rilevamento dei dispositivi?

risposta

14

Questo è quello che uso:

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

Questo compila condizionalmente, in modo da poter ancora costruire per la sim 3.0. Quindi controlla se la classe UIDevice risponde al selettore. Se uno di questi fallisce, non è un iPad.

+0

Questo è se si desidera compilare per 3.0. Dovresti, come detto drootang, compilare per 3.2 ed eseguirlo su un dispositivo 3.0, poiché 3.2 è ciò che stai inviando all'App Store. – conradev

+0

Sono d'accordo, ma non c'è modo di provare in iPHONE Simulator (al contrario di iPad) mentre lo sviluppo per 3.2. Se vuoi provare su entrambi i sim, devi fare questo tipo di trucco. –

5

Credo che la risposta è semplicemente non tentare di eseguire il codice su iPhone simulatore 3.1.3 o precedente. Compilare sempre con un SDK 3.2. Il simulatore dell'iPhone 3.2 ti porterà il simulatore dell'iPad, o compilerà il dispositivo 3.2 per iPhone e metterà l'app su un telefono per testarlo.

Non esiste alcun modo per compilare 3.2 SDK e utilizzare un simulatore 3.1.3 o precedente.

+5

sì, c'è. È possibile creare 3.2 SDK, quindi modificare il target corrente su iPhone 3.1, quindi eseguire "Esegui" o "Debug" non ricostruirlo. –

0

Questo sembra sconfiggere completamente lo scopo di tale funzione. Loro possono essere compilati ed eseguiti solo su iPhone OS 3.2 (iPhone OS 3.2 può essere eseguito solo su iPad ). Quindi se puoi usare UI_USER_INTERFACE_IDIOM(), il risultato sarà sempre quello di indicare un iPad.

Questo è completamente errato. Può essere compilato su SDK di base di 3.2, ma può essere eseguire su qualsiasi sistema operativo, se si imposta il target di distribuzione in modo appropriato.

0

UI_USER_INTERFACE_IDIOM() e UIUserInterfaceIdiomPad possono essere utilizzati su iOS3.2 e verso l'alto, la parte importante è "verso l'alto". Sicuro. iOS3.2 è solo per iPad, ma iOS4.0 e oltre funziona sia su iPhone che su iPad, quindi il controllo non è così inutile come credi.

7

Se questo è l'approccio di Apple raccomandata-by-to runtime dispositivo di rilevamento, che cosa sto facendo male?Qualcuno ha avuto successo nell'utilizzare lo questo approccio al rilevamento dei dispositivi?

Questa è la soluzione per runtime rilevamento:

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

Dopo di che si può facilmente verificare ovunque nel codice:

if (isIPhone) { ... } 

La differenza tra questo e l'utilizzo di #if/#ifdef è che questo è un test di runtime, mentre #if è un test in fase di compilazione.

Penso che il test di runtime sia migliore, perché in questo caso è possibile utilizzare uno solo per ogni versione del sistema operativo. Se si utilizza il controllo in fase di compilazione, è necessario produrre diversi eseguibili per diverse versioni del sistema operativo.

Se il tuo problema è in fase di compilazione, dovresti semplicemente compilare l'ultima versione dell'SDK (vedi anche How to access weak linked framework in iOS?).

5

Invece di qualsiasi materiale a base compilatore che 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 
} 
2

dichiarare di utilizzare questo

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

quindi utilizzare assegno come di seguito

#define DetailLabel_PosX (IS_IPAD ? 200 : 160) 

Ci sono anche alcuni definiscono per il controllo di 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) 
+0

sopra le funzioni non funzionano più – HarshIT

Problemi correlati