¿Cómo detectar el iPhone 5 (dispositivos de pantalla ancha)?
Acabo de actualizar a Xcode 4.5 GM y descubrí que ahora puedes aplicar el tamaño '4" Retina' a tu 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 crear 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 la vista.
¿Cómo debería hacer eso?
En primer lugar, no debe reconstruir todas sus vistas para que se ajusten a una nueva pantalla, ni utilizar diferentes vistas para diferentes tamaños de pantalla.
Utilice 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 alguna documentación al respecto. Esto le ahorrará mucho tiempo.
iOS 6 también ofrece nuevas funciones al respecto.
Asegúrese de leer el registro de cambios de la API de iOS 6 en el sitio web de desarrolladores de Apple. Y compruebe las nuevas capacidades de AutoLayout
de iOS 6 .
Dicho esto, si realmente necesitas detectar el iPhone 5, simplemente puedes 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 fabs
con épsilon está aquí para evitar errores de precisión al comparar puntos flotantes, como se señala en los comentarios de H2CO3.
Entonces, de ahora en adelante puedes usarlo en declaraciones estándar if/else:
if( IS_IPHONE_5 )
{}
else
{}
Editar - Mejor detección
Como afirman algunas personas, esto sólo detecta una pantalla panorámica , no un iPhone 5 real.
Es posible que las próximas versiones del iPod touch también tengan dicha pantalla, por lo que podremos utilizar 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 ancha, y podemos redefinir la IS_IPHONE_5
macro:
#define IS_IPHONE_5 ( IS_IPHONE && IS_WIDESCREEN )
También tenga en cuenta que, como lo indica @LearnCocos2D, estas macros no funcionarán si la aplicación no está optimizada para la pantalla del iPhone 5 (falta la imagen [email protected] ), ya que el tamaño de la pantalla seguirá siendo 320x480 en tal caso. 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: compatibilidad con iOS 8
En iOS 8, la bounds
propiedad de la UIScreen
clase ahora refleja la orientación del dispositivo .
Obviamente, el código anterior no funcionará de inmediato.
Para solucionar este problema, simplemente puede usar la nueva nativeBounds
propiedad, 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 nativeBounds
se miden en píxeles, por lo que para un iPhone 5 la altura será 1136 en lugar de 568.
Si también estás apuntando a iOS 7 o inferior, asegúrate de usar la detección de funciones, ya que llamar nativeBounds
antes de iOS 8 bloqueará tu aplicación:
if( [ [ UIScreen mainScreen ] respondsToSelector: @selector( nativeBounds ) ] )
{
/* Detect using nativeBounds - iOS 8 and greater */
}
else
{
/* Detect using bounds - iOS 7 and lower */
}
Puedes 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 necesitas detectar un iPhone 6 o 6 Plus, utiliza los tamaños de pantalla correspondientes.
Probado y diseñado para cualquier combinación de SDK y SO:
Rápido
Tipos de iPad agregados. El iPad 2 y el iPad mini son iPads sin retina. Mientras que el iPad Mini 2 y superior, el iPad 3, 4, el iPad Air, el Air 2, el Air 3 y el iPad Pro 9.7 tienen la misma resolución lógica de 1024. El iPad Pro tiene una longitud máxima de 1366 .
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 interfaz de usuario es una versión ampliada del iPhone 5. Estas funciones no determinan el tipo de dispositivo, sino el modo de visualización, por lo que 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 interfaz de usuario es una versión ampliada del iPhone 5. Estas funciones no determinan el tipo de dispositivo, sino el modo de visualización, por lo que el iPhone 5 es el resultado deseado en este ejemplo.
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
}
}
Ahora debemos tener en cuenta los tamaños de pantalla del 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"
Me tomé la libertad de poner la macro hecha por Mac en una función C y nombrarla correctamente porque detecta la disponibilidad de pantalla ancha 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 [email protected] . Sin la nueva imagen predeterminada, el iPhone 5 tendrá un tamaño de pantalla normal de 480x320 (en puntos). Por lo tanto, la verificación no es solo para la disponibilidad de pantalla ancha, sino también para que el modo de pantalla ancha esté habilitado .
BOOL isWidescreenEnabled()
{
return (BOOL)(fabs((double)[UIScreen mainScreen].bounds.size.height -
(double)568) < DBL_EPSILON);
}