2010-07-17 13 views
24

En mi aplicación, estoy descargando algunas imágenes de la web (desde mi servidor para ser precisas), para ahorrar algo de ancho de banda y especialmente memoria en el teléfono, las doy en dos resoluciones: 480x320 para la "vieja" serie de iPhone y 960x640 para el iPhone 4 con la pantalla Retina. Ahora necesito poder detectar desde dentro de la aplicación cuando se ejecuta en un dispositivo que admite la pantalla retina. ¿Cómo podría hacer eso?Detectar pantalla retina/iPhone 4 en iPhone SDK

He estado pensando en utilizar el fragmento de código a continuación, que me devolvería un identificador de dispositivo específico como, por ejemplo. "iPhone3", sin embargo, estaría limitando la detección al iPhone4 y tendría que actualizar ese código para cualquier dispositivo posterior con una pantalla 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]; 

¿Hay alguna mejor idea (tal vez es muy obvio, pero me lo perdí)?

Respuesta

32

Acabo de leer un poco en los foros oficiales de desarrolladores de Apple y los problemas se debatieron extensamente allí. La mejor manera para mí parece ser el uso de la propiedad scale de UIScreen. Aunque solo está disponible en iOS 4 y posterior, le dirá todo lo que necesita saber y probablemente desempeñe un papel aún más importante en el futuro (¿Ya se dio cuenta de que la resolución de pantalla del iPad de 1024x768 es exactamente 32/15 * 480x320?)

UIScreen.mainScreen.scale 

Si todavía otra idea no dude en enviar él :)

+0

Esta es la forma correcta de hacerlo. – Elfred

+2

Sí, use esto, no intente nunca consultar en qué dispositivo se está ejecutando, terminará en nada más que dolor. –

+0

Ese es el enfoque correcto, ya que no desea escribir código condicional para el iPhone 4, pero para una pantalla con una escala/resolución diferente. Quién sabe cuándo el iPod recibirá el tratamiento de la retina. – FelixLam

1

Ir con la respuesta de Robin. Otra nota: si necesita verificar el nombre del dispositivo, solo use los métodos en UIDevice.

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

Ejercicio para el lector: por qué la detección del dispositivo (en lugar de las capacidades) siempre es una mala idea. –

23

Aquí hay un código que hacerlo de la manera correcta, tanto para iOS 3.x 4.x:

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

Solo tenga en cuenta que esto también volverá a ser cierto para el modo "iphone simulador" del iPad si comienza en 2x, que puede ser o no lo que usted desea. –

+2

¿Hay alguna solución para el problema 2x en el "simulador de iphone" del iPad? – joelsand

5

consigo el tamaño real de la pantalla (en píxeles) de esta manera:

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

Si está utilizando Cocos2d, intente lo siguiente:

[[CCDirector sharedDirector] winSizeInPixels];

Se devolverá un CGSize con propiedades width y height.

15

una puesta al día sobre la respuesta de Scott Gustafson:

Si es necesario distinguir entre el 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

Aunque ya ha seleccionado una respuesta, hay una mucho más fácil manera cuando se trata específicamente de imágenes, así que lo mencionaré también.

Si incluye dos imágenes en su paquete de los dos tamaños (320x480 y 640x960) y agrega "@ 2x" al final del nombre de archivo de la última imagen, [UIImage imageNamed:] seleccionará automágicamente la imagen más pequeña para mayor dispositivos y el 2x para dispositivos con pantalla Retina, siempre que deje el sufijo de la imagen. Ej .:

2 imágenes llamadas @ "image.png" y @ "[email protected]", ambas incluidas en el paquete de la aplicación.

luego llamar a:

[UIImage imageNamed:@"image"]; 

Así es también como iconos de aplicaciones y el trabajo pantalla de carga.

+0

-1: ¿No leíste el comienzo de la publicación ...? Para citar: "En mi aplicación, estoy ** descargando algunas imágenes de la web **" –

1

Y para aquellos que solo quieren copiar/pegar cómo detectar iphone/iphone_retina/ipad/ipad_retina, esto es lo que terminé haciendo después de leer este hilo. Muy inspirado por la contribución de Guntis Treulands, quien a su vez amplió la respuesta de 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

La práctica normal de nomenclatura sobre el cacao exigiría nombrar el método con una letra inicial minúscula. – 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; 
} 
Cuestiones relacionadas