Domanda

di Apple consiglia utilizzando il seguente codice per rilevare se in esecuzione su un iPad o 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]
}

Il problema è che UI_USER_INTERFACE_IDIOM () e UIUserInterfaceIdiomPad non sono definiti negli SDK precedenti al 3.2. Questo sembra sconfiggere completamente lo scopo di tale funzione a. Essi possono essere compilati ed eseguiti su iPhone OS 3.2 (iPhone OS 3.2 può essere eseguito solo su iPad) solo. Quindi, se è possibile utilizzare UI_USER_INTERFACE_IDIOM (), il risultato sarà sempre per indicare un iPad.

Se si include questo codice e destinazione OS 3.1.3 (il più recente iPhone / iPod Touch OS), al fine di testare il codice universal app iPhone-bound, si otterrà errori del compilatore in quanto i simboli non sono definiti in 3.1. 3 o versioni precedenti, quando si compila per il simulatore di iPhone 3.1.3.

Se questo è il consigliato-by-di Apple approccio alla fase di esecuzione del dispositivo di rilevamento, che cosa sto sbagliando? Qualcuno è riuscito con questo approccio al dispositivo di rilevamento?

È stato utile?

Soluzione

Lo faccio per ottenere il codice per compilare sia in 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
}

Ho anche scritto un post sul blog rapido su di esso qui: http: // www. programbles.com/2010/04/03/compiling-conditional-code-in-universal-iphone-ipad-applications/

Altri suggerimenti

Questo è quello che io uso:

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

Questa condizionalmente compilazione, in modo da poter ancora costruire per la sim 3.0. E poi controlla se le risponde classe UIDevice al selettore. Se uno di questi non riescono, non è un iPad.

  

Se questo è l'approccio raccomandato-by-Apple per runtime   dispositivo di rilevamento, che cosa sto sbagliando? Qualcuno ha avuto successo utilizzando   questo approccio al dispositivo di rilevamento?

Questa è la soluzione per runtime di 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 è il test di runtime, mentre #if è in test in fase di compilazione.

Penso che il test di runtime è meglio, perché si può usare uno exactable per qualsiasi versione del sistema operativo in questo caso. Se si utilizza il check in fase di compilazione, è necessario produrre diversi eseguibili per le diverse versioni del sistema operativo.

Se il problema è errori di compilazione, basta dovrebbe compilare contro dall'ultima versione del SDK (vedi anche Come accedere debole quadro legati in iOS? ).

Credo che la risposta è semplicemente non tentare di eseguire il codice su iPhone simulatore 3.1.3 o versioni precedenti. compilazione Sempre con un 3.2 SDK. Il simulatore di iPhone 3.2 si arriva il simulatore iPad, o compilare per iPhone dispositivo 3.2 e mettere l'applicazione su un telefono per testarlo.

Non c'è modo di compilare contro 3.2 SDK e utilizzare un simulatore 3.1.3 o precedente.

Al posto di qualsiasi uso compilatore basato roba che:

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

dichiarare di utilizzare questo

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

poi usare di controllo, 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 )
  

Questo sembra sconfiggere completamente lo scopo di tale funzione a. Essi   può essere compilato ed eseguito su iPhone solo   OS 3.2 (iPhone OS 3.2 può essere eseguito solo   su iPad). Quindi, se si può usare   UI_USER_INTERFACE_IDIOM (), il risultato   sarà sempre per indicare un iPad.

Questo è completamente errato. Può essere compilato su Base SDK di 3.2, ma può essere run su qualsiasi sistema operativo, se si imposta la destinazione di distribuzione in modo appropriato.

UI_USER_INTERFACE_IDIOM () e UIUserInterfaceIdiomPad può essere utilizzato su iOS3.2 e verso l'alto, la parte importante è la 'verso l'alto'. Sicuro. iOS3.2 è solo per iPad, ma iOS4.0 e al di là corsa su entrambi iPhone e iPad, in modo che il controllo non è così inutile come si pensa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top