¿Cómo detectar el iPhone 5 (dispositivos de pantalla ancha)?


300

Acabo de actualizar a XCode 4.5 GM y descubrí que ahora puede aplicar el tamaño '4 "Retina' a su controlador de vista en el guión gráfico.

Ahora, si quiero crear una aplicación que se ejecute en iPhone 4 y 5, por supuesto, tengo que construir cada ventana dos veces, pero también tengo que detectar si el usuario tiene un iPhone con pantalla de 3.5 "o 4" y luego aplicar el ver.

¿Cómo debo hacer eso?


2
No tiene que construir cada "ventana" dos veces. Solo aquellos que se supone que coinciden exactamente con el tamaño de la pantalla tendrán que ser retransmitidos. La solución parece bastante obvia, simplemente verifique las dimensiones de la ventana y agregue una decisión de caso basada en el tamaño devuelto.
Hasta el

1
Bueno, básicamente eso es cierto, pero quiero usar el tamaño de pantalla adicional de una manera completamente diferente, como lo podría hacer con una pantalla horizontal.
Finn Gaida


¿Debería actualizarse esta pregunta de acuerdo con los nuevos dispositivos? Por ejemplo, "¿Cómo detectar dispositivos iOS por tamaño de pantalla"?
hfossli

Respuestas:


467

En primer lugar, no debe reconstruir todas sus vistas para que se ajusten a una nueva pantalla, ni usar diferentes vistas para diferentes tamaños de pantalla.

Use las capacidades de cambio de tamaño automático de iOS, para que sus vistas puedan ajustarse y adaptarse a cualquier tamaño de pantalla.

Eso no es muy difícil, lea algo de documentación al respecto. Esto le ahorrará mucho tiempo.

iOS 6 también ofrece nuevas características al respecto.
Asegúrese de leer el registro de cambios de la API de iOS 6 en el sitio web del desarrollador de Apple.
Y compruebe las nuevas capacidades de iOS 6 AutoLayout .

Dicho esto, si realmente necesita detectar el iPhone 5, simplemente puede confiar en el tamaño de la pantalla .

[ [ UIScreen mainScreen ] bounds ].size.height

La pantalla del iPhone 5 tiene una altura de 568.
Puedes imaginar una macro para simplificar todo esto:

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

El uso de fabscon el épsilon está aquí para evitar errores de precisión, al comparar puntos flotantes, como se señala en los comentarios de H2CO3.

Entonces, a partir de ahora, puede usarlo en declaraciones if / else estándar:

if( IS_IPHONE_5 )
{}
else
{}

Editar - Mejor detección

Como han dicho algunas personas, esto solo detecta una pantalla panorámica , no un iPhone 5 real.

Las próximas versiones del iPod touch quizás también tengan dicha pantalla, por lo que podemos usar otro conjunto de macros.

Cambiemos el nombre de la macro original IS_WIDESCREEN:

#define IS_WIDESCREEN ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )

Y agreguemos macros de detección de modelos:

#define IS_IPHONE ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPhone" ] )
#define IS_IPOD   ( [ [ [ UIDevice currentDevice ] model ] isEqualToString: @"iPod touch" ] )

De esta manera, podemos asegurarnos de tener un modelo de iPhone Y una pantalla panorámica, y podemos redefinir la IS_IPHONE_5macro:

#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

También tenga en cuenta que, como lo indicó @ LearnCocos2D, estas macros no funcionarán si la aplicación no está optimizada para la pantalla del iPhone 5 (falta la imagen Default-568h@2x.png), ya que el tamaño de la pantalla seguirá siendo 320x480 en un caso.

No creo que esto pueda ser un problema, ya que no veo por qué querríamos detectar un iPhone 5 en una aplicación no optimizada.

IMPORTANTE: soporte para iOS 8

En iOS 8, la boundspropiedad de la UIScreenclase ahora refleja la orientación del dispositivo .
Obviamente, el código anterior no funcionará de fábrica.

Para solucionar esto, simplemente puede usar la nueva nativeBoundspropiedad, en lugar de bounds, ya que no cambiará con la orientación, y se basa en un modo vertical.
Tenga en cuenta que las dimensiones de nativeBoundsse miden en píxeles, por lo que para un iPhone 5 la altura será de 1136 en lugar de 568.

Si también está apuntando a iOS 7 o inferior, asegúrese de usar la detección de funciones, ya que llamar nativeBoundsantes de iOS 8 bloqueará su aplicación:

if( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] )
{
    /* Detect using nativeBounds - iOS 8 and greater */
}
else
{
    /* Detect using bounds - iOS 7 and lower */
}

Puede adaptar las macros anteriores de la siguiente manera:

#define IS_WIDESCREEN_IOS7 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
#define IS_WIDESCREEN_IOS8 ( fabs( ( double )[ [ UIScreen mainScreen ] nativeBounds ].size.height - ( double )1136 ) < DBL_EPSILON )
#define IS_WIDESCREEN      ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_WIDESCREEN_IOS8 : IS_WIDESCREEN_IOS7 )

Y obviamente, si necesita detectar un iPhone 6 o 6 Plus, use los tamaños de pantalla correspondientes.


77
Esto está mal, tendrás que usarlo#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == 568 )
Fabian Kreiser

28
@ H2CO3: Tenga en cuenta que la comparación con DBL_EPSILONno es necesaria aquí, y que la ==comparación no fallará: solo es necesario hacer una comparación usando las diferencias de esta manera si el valor de coma flotante no puede expresarse como un número exacto (como 1.0/3.0*3.0por ejemplo). Lea este artículo para obtener más información;)
AliSoftware

2
Esta respuesta no es correcta. ¿Por qué recibió tantos pulgares? no puede usar solo la altura para determinar si se trata de pantalla panorámica. amigo ...
OMGPOP

55
Puedo agregar: Si desea que esto funcione con el simulador, use esto: #define IS_IPHONE (([[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone"]) || ([[[[UIDevice currentDevice] model] isEqualToString: @ "iPhone Simulator"]))
david

31
Esta respuesta es una locura. Esto de recomendar no comparar este tipo particular de flotadores (que en realidad son, y si sabes que Apple debería saber que siempre serán enteros) con == no tiene sentido y complica demasiado las cosas. Además, creo que es mejor usar UI_USER_INTERFACE_IDIOM () para la detección de iPhone, ya que funciona bien tanto en el dispositivo como en el simulador (y podría ser más rápido que el enfoque UIDevice). Esto funciona bien y es mucho más fácil de leer: #define IS_IPHONE5 (UI_USER_INTERFACE_IDIOM () == UIUserInterfaceIdiomPhone && [UIScreen mainScreen] .bounds.size.height == 568)
Ricardo Sanchez-Saez

232

Probado y diseñado para cualquier combinación de SDK y OS:

Rápido

Tipos de iPad agregados. iPad 2 y iPad mini son iPads sin retina. Mientras que el iPad Mini 2 y superior, iPad 3, 4, iPad Air, Air 2, Air 3 y iPad Pro 9.7 tienen la misma resolución lógica de 1024. iPad Pro tiene una longitud máxima de 1366. Referencia

import UIKit

public enum DisplayType {
    case unknown
    case iphone4
    case iphone5
    case iphone6
    case iphone6plus
    case iPadNonRetina
    case iPad
    case iPadProBig
    static let iphone7 = iphone6
    static let iphone7plus = iphone6plus
}

public final class Display {
    class var width:CGFloat { return UIScreen.main.bounds.size.width }
    class var height:CGFloat { return UIScreen.main.bounds.size.height }
    class var maxLength:CGFloat { return max(width, height) }
    class var minLength:CGFloat { return min(width, height) }
    class var zoomed:Bool { return UIScreen.main.nativeScale >= UIScreen.main.scale }
    class var retina:Bool { return UIScreen.main.scale >= 2.0 }
    class var phone:Bool { return UIDevice.current.userInterfaceIdiom == .phone }
    class var pad:Bool { return UIDevice.current.userInterfaceIdiom == .pad }
    class var carplay:Bool { return UIDevice.current.userInterfaceIdiom == .carPlay }
    class var tv:Bool { return UIDevice.current.userInterfaceIdiom == .tv }
    class var typeIsLike:DisplayType {
        if phone && maxLength < 568 {
            return .iphone4
        }
        else if phone && maxLength == 568 {
                return .iphone5
        }
        else if phone && maxLength == 667 {
            return .iphone6
        }
        else if phone && maxLength == 736 {
            return .iphone6plus
        }
        else if pad && !retina {
            return .iPadNonRetina
        }
        else if pad && retina && maxLength == 1024 {
            return .iPad
        }
        else if pad && maxLength == 1366 {
            return .iPadProBig
        }
        return .unknown
    }
}

Véalo en acción https://gist.github.com/hfossli/bc93d924649de881ee2882457f14e346

Nota: Si, por ejemplo, el iPhone 6 está en modo ampliado, la IU es una versión ampliada del iPhone 5. Estas funciones no determinan el tipo de dispositivo, pero el modo de visualización, por lo tanto, el iPhone 5 es el resultado deseado en este ejemplo.

C objetivo

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)

#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define IS_ZOOMED (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

#define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

Uso: http://pastie.org/9687735

Nota: Si, por ejemplo, el iPhone 6 está en modo ampliado, la IU es una versión ampliada del iPhone 5. Estas funciones no determinan el tipo de dispositivo, pero el modo de visualización, por lo tanto, el iPhone 5 es el resultado deseado en este ejemplo.


1
iPhone 5 informará un tamaño de pantalla normal de 480x320, sin la nueva imagen predeterminada. Para mí este es un comportamiento deseado.
hfossli el

3
Una adición posiblemente útil es la #define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0)que ayudará a determinar la diferencia entre iPhone4 y iPhone5 y iPad Retina y no retina
bshirley

1
Estoy en desacuerdo. Creo que la terminología de 'pantalla panorámica' debería dejarse de lado ya que está desactualizada rápidamente.
hfossli

1
@Dvole así es como se comporta iOS 8. Úselo SCREEN_MAX_LENGTHpara obtener 568 en todas las rotaciones en el iPhone 5.
hfossli

1
@MattParkins Sugeriría utilizar comprobaciones de modelo más robustas stackoverflow.com/questions/13366976/… .
hfossli

69

Solución realmente simple

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    if(result.height == 568)
    {
        // iPhone 5
    }
}

1
jaja corto y simpel, hizo lo mismo :) golpes por mantener bajo los gastos generales! poner cosas en una macro no es un desafío ...
benjamin.ludwig

2
Bueno, no poner las cosas en macro o funciones es propenso a no estar SECO ... Desde el momento en que debe hacer esta comprobación más de una vez ...
hfossli

Sí, pero definir macro como se muestra arriba, es más conveniente y fácil, no necesita pegar escribir esto si ... cada vez.
Resty

Gracias, me salvaste la vida: D, pero no sé por qué Macro: #define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] límites] .size.height == 568.0) ==> No funciona en el simulador iOS 7.1, antes que sigo trabajando en XCode 4.6. OMG iOS 7.1 y Xcode 5
Linh Nguyen

respuesta actualizada a continuación para tener en cuenta los tamaños de pantalla de iPhone 6 y 6 plus
Sam B

28

Ahora tenemos que tener en cuenta los tamaños de pantalla de iPhone 6 y 6Plus. Aquí hay una respuesta actualizada

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
    //its iPhone. Find out which one?

    CGSize result = [[UIScreen mainScreen] bounds].size;
    if(result.height == 480)
    {
        // iPhone Classic
    }
    else if(result.height == 568)
    {
        // iPhone 5
    }
    else if(result.height == 667)
    {
        // iPhone 6
    }
   else if(result.height == 736)
    {
        // iPhone 6 Plus
    }
}
else
{
     //its iPad
}

Alguna información útil

iPhone 6 Plus   736x414 points  2208x1242 pixels    3x scale    1920x1080 physical pixels   401 physical ppi    5.5"
iPhone 6        667x375 points  1334x750 pixels     2x scale    1334x750 physical pixels    326 physical ppi    4.7"
iPhone 5        568x320 points  1136x640 pixels     2x scale    1136x640 physical pixels    326 physical ppi    4.0"
iPhone 4        480x320 points  960x640 pixels      2x scale    960x640 physical pixels     326 physical ppi    3.5"
iPhone 3GS      480x320 points  480x320 pixels      1x scale    480x320 physical pixels     163 physical ppi    3.5"

es simplemente no funciona para mí iPhone 5 iPhone 4 decidido como 6+ no decidió nada Oh lo tengo estoy en el paisaje que debería cambiar la altura con un ancho :)
atarLas

si su aplicación está en modo horizontal, asegúrese de cambiar result.height to result.width
Sam B

hmm ... en el iPhone 4 (iOS 6.0) no se intercambió :( podría ser un problema de iOS 6.0 o un iPhone 4?
ColdSteel

Bien, verifiqué la vista intercambiada solo en iOS 8 y superior
ColdSteel

iPhone 6 dando altura = 568
MaxEcho

15

Me tomé la libertad de poner la macro de Macmade en una función C y nombrarla correctamente porque detecta la disponibilidad de pantalla panorámica y NO necesariamente el iPhone 5.

La macro tampoco detecta la ejecución en un iPhone 5 en caso de que el proyecto no incluya Default-568h@2x.png . Sin la nueva imagen predeterminada, el iPhone 5 informará un tamaño de pantalla normal de 480x320 (en puntos). Por lo tanto, la comprobación no es solo para la disponibilidad de pantalla panorámica, sino también para habilitar el modo de pantalla panorámica .

BOOL isWidescreenEnabled()
{
    return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height - 
                                               (double)568) < DBL_EPSILON);
}

Todavía prefiero las macros, por razones de rendimiento. Por favor, vea la edición de mi respuesta. También verifica el modelo.
Macmade

1
También tiene razón al decir que un iPhone 5 informará un tamaño de pantalla normal de 480x320, sin la nueva imagen predeterminada. Pero creo que no tiene sentido detectar un iPhone 5 en una aplicación no optimizada. :)
Macmade

@Macmade De hecho, no tiene sentido, pero es bueno tenerlo en cuenta en caso de que la detección no funcione. Además, las funciones pueden ser inlined. También estarán en línea donde el optimizador del compilador cree que es una buena idea y donde puede saber que está permitido (por ejemplo, la función está en el mismo módulo). Implementar cosas como esta a través de una función a veces puede traer verificación de tipo adicional.
Ivan Vučica

44
La pregunta relacionada con el rendimiento es, ¿por qué ejecutaría esta verificación miles de veces durante su ciclo de renderizado? De lo contrario, el rendimiento no es un problema, es claro y evita los efectos secundarios de mayor importancia.
LearnCocos2D

Le di un +1 para esto porque me gusta la función separada en lugar de una macro, pero tengo que señalar que no es realmente correcta o completa. Para detectar la pantalla panorámica, no mire la altura de la pantalla. En cambio, mire la relación de aspecto y devuelva verdadero solo si la relación de aspecto es mayor o igual que 16: 9.
Todd Lehman

11

Aquí están nuestros códigos, prueba aprobada en ios7 / ios8 para iphone4, iphone5, ipad, iphone6, iphone6p, no importa en dispositivos o simulador:

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) // iPhone and       iPod touch style UI

#define IS_IPHONE_5_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0f)
#define IS_IPHONE_6_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0f)
#define IS_IPHONE_6P_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS7 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 568.0f)

#define IS_IPHONE_5_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 568.0f)
#define IS_IPHONE_6_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 667.0f)
#define IS_IPHONE_6P_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 736.0f)
#define IS_IPHONE_4_AND_OLDER_IOS8 (IS_IPHONE && ([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) < 568.0f)

#define IS_IPHONE_5 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_5_IOS8 : IS_IPHONE_5_IOS7 )
#define IS_IPHONE_6 ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6_IOS8 : IS_IPHONE_6_IOS7 )
#define IS_IPHONE_6P ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_6P_IOS8 : IS_IPHONE_6P_IOS7 )
#define IS_IPHONE_4_AND_OLDER ( ( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] ) ? IS_IPHONE_4_AND_OLDER_IOS8 : IS_IPHONE_4_AND_OLDER_IOS7 )

Estoy probando en un iPhone 6P y mi declaración if está cayendo en la condición IS_IPHONE_5? ¿Cómo puede ser esto, tu código se ve bien? Copié y pegué directamente con un simple if / else y sé que mi teléfono es un 6 plus con iOS 8.3.
whyoz

7

Usé la respuesta de hfossli y la traduje a Swift

let IS_IPAD = UIDevice.currentDevice().userInterfaceIdiom == .Pad
let IS_IPHONE = UIDevice.currentDevice().userInterfaceIdiom == .Phone
let IS_RETINA = UIScreen.mainScreen().scale >= 2.0

let SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width
let SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height
let SCREEN_MAX_LENGTH = max(SCREEN_WIDTH, SCREEN_HEIGHT)
let SCREEN_MIN_LENGTH = min(SCREEN_WIDTH, SCREEN_HEIGHT)

let IS_IPHONE_4_OR_LESS = (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
let IS_IPHONE_5 = (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
let IS_IPHONE_6 = (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
let IS_IPHONE_6P = (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)

6

Esta es la macro para mi proyecto cocos2d. debería ser igual para otras aplicaciones.

#define WIDTH_IPAD 1024
#define WIDTH_IPHONE_5 568
#define WIDTH_IPHONE_4 480
#define HEIGHT_IPAD 768
#define HEIGHT_IPHONE 320

#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)

//width is height!
#define IS_IPHONE_5 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_5 )
#define IS_IPHONE_4 ( [ [ UIScreen mainScreen ] bounds ].size.height == WIDTH_IPHONE_4 )

#define cp_ph4(__X__, __Y__) ccp(cx_ph4(__X__), cy_ph4(__Y__))
#define cx_ph4(__X__) (IS_IPAD ? (__X__ * WIDTH_IPAD / WIDTH_IPHONE_4) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPHONE_4) : (__X__)))
#define cy_ph4(__Y__) (IS_IPAD ? (__Y__ * HEIGHT_IPAD / HEIGHT_IPHONE) : (__Y__))

#define cp_pad(__X__, __Y__) ccp(cx_pad(__X__), cy_pad(__Y__))
#define cx_pad(__X__) (IS_IPAD ? (__X__) : (IS_IPHONE_5 ? (__X__ * WIDTH_IPHONE_5 / WIDTH_IPAD) : (__X__ * WIDTH_IPHONE_4 / WIDTH_IPAD)))
#define cy_pad(__Y__) (IS_IPAD ? (__Y__) : (__Y__ * HEIGHT_IPHONE / HEIGHT_IPAD))

5
if ((int)[[UIScreen mainScreen] bounds].size.height == 568)
{
    // This is iPhone 5 screen
} else {
    // This is iPhone 4 screen
}

3

En Swift, proyecto iOS 8+ en el que me gusta hacer una extensión UIScreen, como:

extension UIScreen {

    var isPhone4: Bool {
        return self.nativeBounds.size.height == 960;
    }

    var isPhone5: Bool {
        return self.nativeBounds.size.height == 1136;
    }

    var isPhone6: Bool {
        return self.nativeBounds.size.height == 1334;
    }

    var isPhone6Plus: Bool {
        return self.nativeBounds.size.height == 2208;
    }

}

(NOTA: nativeBoundsestá en píxeles).

Y luego el código será como:

if UIScreen.mainScreen().isPhone4 {
    // do smth on the smallest screen
}

Entonces, el código deja en claro que esta es una verificación para la pantalla principal, no para el modelo de dispositivo.


2

Tomando prestado de la respuesta de Samrat Mazumdar, aquí hay un método corto que estima el tamaño de la pantalla del dispositivo. Funciona con los dispositivos más recientes, pero puede fallar en los futuros (como podrían hacer todos los métodos de adivinanzas). También se confundirá si el dispositivo se está duplicando (devuelve el tamaño de la pantalla del dispositivo, no el tamaño de la pantalla reflejada)

#define SCREEN_SIZE_IPHONE_CLASSIC 3.5
#define SCREEN_SIZE_IPHONE_TALL 4.0
#define SCREEN_SIZE_IPAD_CLASSIC 9.7

+ (CGFloat)screenPhysicalSize
{
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        if (result.height < 500)
            return SCREEN_SIZE_IPHONE_CLASSIC;  // iPhone 4S / 4th Gen iPod Touch or earlier
        else
            return SCREEN_SIZE_IPHONE_TALL;  // iPhone 5
    }
    else
    {
        return SCREEN_SIZE_IPAD_CLASSIC; // iPad
    }
} 

Necesita revisión para iPad mini que, no creo que pueda determinar en esta mansión.
Daniel

Sí, el iPad mini tiene la misma resolución que el iPad2, por lo que este método no funciona para eso. No estoy seguro de cómo manejar ese caso en este momento ...
Jeff Hay

1
Se supone que no debes hacerlo. Puede verificar el identificador del dispositivo para "iPad 2,5". También necesita verificar 2,6 y 2,7, la versión solo wifi, gsm y CDMA. Pero eso significa que se lanzará el próximo iPad mini y también deberá actualizar el código duro a esos identificadores que no puede conocer de antemano. No puedes saber cuando estás en un iPad mini porque realmente no deberías intentar "optimizar" para una pantalla más pequeña
Daniel

2

Creo que debería ser bueno si esta macro funcionará en el dispositivo y el simulador, a continuación se encuentra la solución.

#define IS_WIDESCREEN (fabs((double)[[UIScreen mainScreen]bounds].size.height - (double)568) < DBL_EPSILON)
#define IS_IPHONE (([[[UIDevice currentDevice] model] isEqualToString:@"iPhone"]) || ([[[UIDevice currentDevice] model] isEqualToString: @"iPhone Simulator"]))
#define IS_IPOD   ([[[UIDevice currentDevice]model] isEqualToString:@"iPod touch"])
#define IS_IPHONE_5 ((IS_IPHONE || IS_IPOD) && IS_WIDESCREEN)

2

Descubrí que las respuestas no incluyen un caso especial para Simuladores.

#define IS_WIDESCREEN ( [ [ UIScreen mainScreen ] bounds ].size.height == 568  )
#define IS_IPHONE ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPhone"].location != NSNotFound)
#define IS_IPAD ([[ [ UIDevice currentDevice ] model ] rangeOfString:@"iPad"].location != NSNotFound)
#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )

2
+(BOOL)isDeviceiPhone5
{
    BOOL iPhone5 = FALSE;

    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    if (screenBounds.size.height == 568)
    {
        // code for 4-inch screen
        iPhone5 = TRUE;
    }
    else
    {
        iPhone5 = FALSE;
        // code for 3.5-inch screen
    }
    return iPhone5;

}

iPhone5 = FALSE;es innecesaria porque la variable tiene ya ese valor si no ha cambiado
mcont

1
CGFloat height = [UIScreen mainScreen].bounds.size.height;

NSLog(@"screen soze is %f",height);

  if (height>550) {

          // 4" screen-do some thing
     }

  else if (height<500) {

        // 3.5 " screen- do some thing

     }


1

De esta manera puede detectar la familia de dispositivos.

    #import <sys/utsname.h>
    NSString* deviceName()
    {
        struct utsname systemInformation;
        uname(&systemInformation);
        NSString *result = [NSString stringWithCString:systemInformation.machine
                                              encoding:NSUTF8StringEncoding];
        return result;
    }

    #define isIPhone5  [deviceName() rangeOfString:@"iPhone5,"].location != NSNotFound
    #define isIPhone5S [deviceName() rangeOfString:@"iPhone6,"].location != NSNotFound

1

Si el proyecto se crea utilizando Xcode 6, utilice el código mencionado a continuación para detectar los dispositivos.

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136){
            printf("Device Type : iPhone 5,5S/iPod 5 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1334){
            printf("Device Type : iPhone 6 ");

        }else if([[UIScreen mainScreen] nativeBounds].size.height == 2208){
            printf("Device Type : iPhone 6+ ");

        }
    }
}else{
    printf("Device Type : iPad");
}

Si el proyecto se creó en Xcode 5 y se abrió en Xcode 6, utilice el código mencionado a continuación para detectar los dispositivos (este código funciona si no se asignan imágenes de lanzamiento para iPhone 6,6+)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] nativeBounds].size.width,(int)[[UIScreen mainScreen] nativeBounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
       if([[UIScreen mainScreen] nativeBounds].size.height == 960 || [[UIScreen mainScreen] nativeBounds].size.height == 480){
            printf("Device Type : iPhone 4,4s");
            appType=1;
        }else if([[UIScreen mainScreen] nativeBounds].size.height == 1136 || [[UIScreen mainScreen] nativeBounds].size.height == 1704){
            printf("Device Type : iPhone 5,5S,6,6S/iPod 5 ");
            appType=3;
        }
    }
}else{
    printf("Device Type : iPad");
    appType=2;
}

Si todavía usa Xcode 5 todos juntos, use el siguiente código para detectar los dispositivos (no se detectarán iPhone 6 y 6+)

printf("\nDetected Resolution : %d x %d\n\n",(int)[[UIScreen mainScreen] bounds].size.width,(int)[[UIScreen mainScreen] bounds].size.height);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone){
    if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
    {
        CGSize result = [[UIScreen mainScreen] bounds].size;
        CGFloat scale = [UIScreen mainScreen].scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
        if(result.height == 960 || result.height == 480){
            printf("Device Type : iPhone 4,4S ");

        }else if(result.height == 1136){
            printf("Device Type : iPhone 5s/iPod 5");

        }
    }
}else{
    printf("Device Type : iPad");

}

1
  1. Agregue un 'Nuevo archivo Swift' -> AppDelegateEx.swift

  2. agregar una extensión a AppDelegate

    import UIKit
    extension AppDelegate {
         class func isIPhone5 () -> Bool{
             return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 568.0
        }
        class func isIPhone6 () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 667.0
        }
        class func isIPhone6Plus () -> Bool {
            return max(UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) == 736.0
        }  
    }
  3. uso:

        if AppDelegate.isIPhone5() {
            collectionViewTopConstraint.constant = 2
        }else if AppDelegate.isIPhone6() {
            collectionViewTopConstraint.constant = 20
        }

1

En Swift 3 puedes usar mi clase simple KRDeviceType.

https://github.com/ulian-onua/KRDeviceType

Está bien documentado y admite operadores ==,> =, <=.

Por ejemplo, para detectar si el dispositivo tiene límites de iPhone 6 / 6s / 7, puede usar la siguiente comparación:

if KRDeviceType() == .iPhone6 {
// Perform appropiate operations
}

Para detectar si el dispositivo tiene límites de iPhone 5 / 5S / SE o anterior (iPhone 4s), puede usar la siguiente comparación:

if KRDeviceType() <= .iPhone5 {   //iPhone 5/5s/SE of iPhone 4s
// Perform appropiate operations (for example, set up constraints for those old devices)
}

1

Esto ha sido respondido cientos de veces, pero esta solución funcionó mejor para mí y me ayudó a resolver el problema cuando se introducen nuevos dispositivos y no tengo un tamaño definido.

Ayudante de Swift 5:

extension UIScreen {
    func phoneSizeInInches() -> CGFloat {
        switch (self.nativeBounds.size.height) {
        case 960, 480:
            return 3.5  //iPhone 4
        case 1136:
            return 4    //iPhone 5
        case 1334:
            return 4.7  //iPhone 6
        case 2208:
            return 5.5  //iPhone 6 Plus
        case 2436:
            return 5.8  //iPhone X
        case 1792:
            return 5.5  //iPhone XR
        case 2688:
            return 6.5  //iPhone XS Max
        default:
            let scale = self.scale
            let ppi = scale * 163
            let width = self.bounds.size.width * scale
            let height = self.bounds.size.height * scale
            let horizontal = width / ppi, vertical = height / ppi
            let diagonal = sqrt(pow(horizontal, 2) + pow(vertical, 2))
            return diagonal
        }
    }
}

Esto se debe a que es fácil memorizar los tamaños en pulgadas de un teléfono, como un dispositivo de "5.5 pulgadas" o "4.7 pulgadas", pero es difícil recordar los tamaños de píxeles exactos.

if UIScreen.main.phoneSizeInInches() == 4 {
  //do something with only 4 inch iPhones
}

Esto también te da la oportunidad de hacer algo como esto:

if UIScreen.main.phoneSizeInInches() < 5.5 {
  //do something all iPhones smaller than the plus
}

El valor predeterminado: intenta usar el tamaño y la escala de la pantalla para tratar de calcular las pulgadas diagonales. Esto es en caso de que aparezca un nuevo tamaño de dispositivo, hará todo lo posible para determinarlo y el código, como el último ejemplo, debería funcionar.


0

use el siguiente código:

CGFloat screenScale = [[UIScreen mainScreen] scale];

CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale); 

if (screenSize.height==1136.000000)
{ 
    // Here iPhone 5 View

    // Eg: Nextview~iPhone5.Xib
} else {
   // Previous Phones 

   // Eg : Nextview.xib
}

0

Aquí está la prueba correcta del dispositivo, sin depender de la orientación

- (BOOL)isIPhone5
{
    CGSize size = [[UIScreen mainScreen] bounds].size;
    if (MIN(size.width,size.height) == 320 && MAX(size.width,size.height == 568)) {
        return YES;
    }
    return NO;
}

-2

Se utiliza para detectar dispositivos iPhone y iPad de todos los versons.

#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IS_IPHONE_5 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)
#define IS_IPHONE_6 (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)
#define IS_IPHONE_6_PLUS (IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0)
#define IS_RETINA ([[UIScreen mainScreen] scale] == 2.0) 

iPhone 6 no tiene pantalla retina?
vikingosegundo

iPhone6 ​​tiene la pantalla ratina (@ 2X). y iPhone6 ​​plus tiene la pantalla HD (@ 3X).
Vaibhav Sharma

Entonces, si se prueba IS_RETINAen un iPhone 6 plus, ¿se ejecuta el código 1x?
vikingosegundo


1
no lo entiendes: tus reglas cederán @1x, donde deberían ceder @3x. de todos modos: como estás simplemente copiando y pegando: -1
vikingosegundo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.