2010-07-17 13 views
24

Nella mia applicazione sto scaricando alcune immagini dal web (dal mio server per essere precisi), al fine di salvare un po 'di banda e soprattutto di memoria sul telefono, li fornisco in due risoluzioni: 480x320 per la "vecchia" serie di iPhone e in 960x640 per l'iPhone 4 con il display retina. Ora devo essere in grado di rilevare dall'interno dell'applicazione quando è in esecuzione su un dispositivo che supporta la retina. Come potrei farlo?Rileva retina schermo/iPhone 4 in iPhone SDK

Ho pensato di utilizzare il frammento di codice al di sotto del quale mi restituirebbe uno specifico identificatore di dispositivo come ad es. "iPhone3", tuttavia, limiterei il rilevamento a iPhone4 e avrei bisogno di aggiornare quel codice per ogni dispositivo successivo con display retina.

size_t size; 

// Set 'oldp' parameter to NULL to get the size of the data 
// returned so we can allocate appropriate amount of space 
sysctlbyname("hw.machine", NULL, &size, NULL, 0); 

// Allocate the space to store name 
char *name = malloc(size); 

// Get the platform name 
sysctlbyname("hw.machine", name, &size, NULL, 0); 

// Place name into a string 
NSString *machine = [NSString stringWithCString:name]; 

Esiste una soluzione migliore (forse è molto evidente ma l'ho persa)?

risposta

32

Ho appena letto alcuni forum ufficiali di Apple Developers e le questioni sono state discusse a lungo. Il modo migliore per me sembra essere l'utilizzo della proprietà scale di UIScreen. Sebbene sia disponibile solo in iOS 4 e versioni successive, ti dirà tutto quello che devi sapere e molto probabilmente avrà un ruolo ancora più importante in futuro (hai già notato che la risoluzione dello schermo dell'iPad di 1024x768 è esattamente 32/15 * 480x320?).

UIScreen.mainScreen.scale 

Se avete ancora un'altra idea non esitate a postare it :)

+0

questo è il modo corretto di farlo. – Elfred

+2

Sì, usa questo, non provare mai a interrogare su quale dispositivo stai usando, finirà solo con il dolore. –

+0

Questo è l'approccio corretto, in quanto non si desidera scrivere codice condizionale per l'iPhone 4 ma per un display con una scala/risoluzione diversa. Chissà quando l'iPod avrà il trattamento della retina. – FelixLam

1

andare con la risposta di Robin. Un'altra nota: se hai bisogno di controllare il nome del dispositivo, usa i metodi su UIDevice.

[[UIDevice currentDevice] model]; 
[[UIDevice currentDevice] systemName]; 
[[UIDevice currentDevice] systemVersion]; 
+1

Esercizio per il lettore: perché rilevare il dispositivo (invece delle capacità) è sempre una cattiva idea. –

23

Ecco il codice per farlo nel modo giusto sia per 3.xe 4.x iOS:

BOOL hasHighResScreen = NO; 
if ([UIScreen instancesRespondToSelector:@selector(scale)]) { 
    CGFloat scale = [[UIScreen mainScreen] scale]; 
    if (scale > 1.0) { 
     hasHighResScreen = YES; 
    } 
} 
+0

State attenti che ciò restituirà true anche per la modalità "iphone simulator" dell'iPad se inizia con 2x, che può essere o non essere quello che volete. –

+2

Esiste una soluzione alternativa per il problema 2x sul "simulatore iphone" dell'iPad? – joelsand

5

ottengo dimensioni dello schermo vero e proprio (in pixel) in questo modo:

UIScreen *MainScreen = [UIScreen mainScreen]; 
UIScreenMode *ScreenMode = [MainScreen currentMode]; 
CGSize Size = [ScreenMode size]; // <--- Real screen size 
1
UIScreen *MainScreen = [UIScreen mainScreen]; 
UIScreenMode *ScreenMode = [MainScreen currentMode]; 
CGSize Size = [ScreenMode size]; // <--- Real screen size 
0

Se stai usando Cocos2d, provare quanto segue:

[[CCDirector sharedDirector] winSizeInPixels];

Restituirà un CGSize con le proprietà width e height.

15

Un piccolo aggiornamento su risposta di Scott Gustafson:

Se abbiamo bisogno di distinguere tra iPad/Retina/iPhone:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    { 
     CGFloat scale = [[UIScreen mainScreen] scale]; 

      if (scale > 1.0) 
      { 
       //iPad retina screen 
      } 
      else 
      { 
       //iPad screen 
      } 
    } 
    else 
    { 
     if ([UIScreen instancesRespondToSelector:@selector(scale)]) 
     { 
       CGFloat scale = [[UIScreen mainScreen] scale]; 

       if (scale > 1.0) 
       { 
        if([[ UIScreen mainScreen ] bounds ].size.height == 568) 
        { 
         //iphone 5 
        } 
        else 
        { 
         //iphone retina screen 
        } 
       } 
       else 
       { 
        //iphone screen 
       } 
     } 
    } 
-1

Anche se hai già selezionato una risposta, c'è un molto più facile modo quando si tratta specificamente di immagini quindi ne parlerò anche io.

Se si includono due immagini nel pacchetto delle due dimensioni (320x480 e 640x960) e si aggiunge "@ 2x" alla fine del nome file di quest'ultima immagine, [UIImage imageNamed:] selezionerà automaticamente l'immagine più piccola per gli anziani dispositivi e il 2x per dispositivi con display retina, a patto di aver omesso il suffisso dell'immagine. Es .:

2 immagini denominate @ "image.png" e @ "[email protected]", entrambe incluse nel pacchetto dell'app.

quindi chiamare:

[UIImage imageNamed:@"image"]; 

Questo è anche il modo icone delle applicazioni e il lavoro schermata di caricamento.

+0

-1: non hai letto l'inizio del post ...? Per citare, "Nella mia applicazione sono ** scaricando alcune immagini dal web **" –

1

E per coloro che vogliono solo copiare/incollare come rilevare iphone/iphone_retina/ipad/ipad_retina, ecco cosa ho finito dopo aver letto questa discussione. Fortemente ispirato dal contributo di Guntis Treulands, che a sua volta ha ampliato la risposta di Scott Gustafsons.

- (NSString *) yesButWhichDeviceIsIt {  
    BOOL hasRetina = NO; 
    if ([UIScreen instancesRespondToSelector:@selector(scale)]) { 
     CGFloat scale = [[UIScreen mainScreen] scale]; 
     if (scale > 1.0) { 
      hasRetina = YES; 
     } 
    } 
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
     if (hasRetina) { 
      return @"iPad retina"; 
     } else { 
      return @"iPad"; 
     } 
    } else { 
     if (hasRetina) { 
      return @"iPhone retina"; 
     } else { 
      return @"iPhone"; 
     }   
    } 
} 
0
+(BOOL)Retina{ 
     return ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))?1:0; } 
+2

Normale pratica di denominazione del cacao detterebbe il nome del metodo con una lettera iniziale minuscola. – Monolo

3
- (BOOL)isRetina { 

    BOOL isRetina = NO; 

    if ([UIScreen instancesRespondToSelector:@selector(scale)]) { 
     CGFloat scale = [[UIScreen mainScreen] scale]; 
     if (scale > 1.0) { 
      isRetina = YES; 
     } 
    } 

    return isRetina; 
} 


- (CGSize)sizeInPixels { 

    CGRect appFrame = [[UIScreen mainScreen] applicationFrame]; 
    CGSize screenSize = CGSizeMake(appFrame.size.width, appFrame.size.height); 

    return [self isRetina] ? CGSizeMake(screenSize.width * 2, screenSize.height * 2) : screenSize; 
} 
Problemi correlati