Mi aplicación iOS utiliza una altura personalizada para lo UINavigationBar
que genera algunos problemas en el nuevo iPhone X.
¿Alguien sabe cómo detectar de manera confiable mediante programación (en Objective-C) si una aplicación se ejecuta en iPhone X?
EDITAR:
Por supuesto, es posible verificar el tamaño de la pantalla, sin embargo, me pregunto si hay algún método "integrado" TARGET_OS_IPHONE
para detectar iOS ...
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (screenSize.height == 812)
NSLog(@"iPhone X");
}
EDITAR 2:
No creo que mi pregunta sea un duplicado de la pregunta vinculada. Por supuesto, hay métodos para "medir" diferentes propiedades del dispositivo actual y usar los resultados para decidir qué dispositivo se usa. Sin embargo, este no era el punto real de mi pregunta, ya que traté de enfatizar en mi primera edición.
La pregunta real es: "¿Es posible detectar directamente si el dispositivo actual es un iPhone X (por ejemplo, mediante alguna función del SDK) o tengo que usar mediciones indirectas" ?
Según las respuestas dadas hasta ahora, supongo que la respuesta es "No, no hay métodos directos. Las medidas son el camino a seguir".
fuente
Respuestas:
Según su pregunta, la respuesta es no. No hay métodos directos. Para obtener más información, puede obtener la información aquí:
y
La altura del iPhone X es de 2436 px
Desde tamaños de pantalla del dispositivo y resoluciones :
Desde los tamaños y orientaciones de la pantalla del dispositivo :
Swift 3 y posterior :
Objetivo-C :
Xamarin.iOS :
Basado en su pregunta de la siguiente manera:
O utilizar
screenSize.height
como flotante812.0f
no int812
.Para obtener más información, puede consultar la siguiente página en las Directrices de interfaz humana de iOS:
Rápido :
Detectar con
topNotch
:Objetivo-C :
ACTUALIZACIÓN :
No use la
userInterfaceIdiom
propiedad para identificar el tipo de dispositivo, como explica la documentación de userInterfaceIdiom :Es decir, esta propiedad solo se usa para identificar el estilo de vista de la aplicación en ejecución. Sin embargo, la aplicación de iPhone (no la universal) podría instalarse en el dispositivo iPad a través de la tienda de aplicaciones, en ese caso,
userInterfaceIdiom
devolverá elUIUserInterfaceIdiomPhone
.La forma correcta es obtener el nombre de la máquina a través de
uname
. Verifique lo siguiente para más detalles:fuente
userInterfaceIdiom
también devolverá elUIUserInterfaceIdiomPhone
. Esta respuesta es incorrecta.Otra posibilidad, que funciona en iOS 11 y iOS 12 porque el iPhone X es el único con una muesca en la parte superior y un recuadro de 44. Eso es lo que realmente estoy detectando aquí:
C objetivo:
Swift 4:
Y, por supuesto, es posible que deba verificar las inserciones del área segura izquierda y derecha si está en orientación horizontal.
Editar: _window es la UIWindow de AppDelegate, donde esta comprobación se realiza en la aplicación didFinishLaunchingWithOptions.
Respuesta actualizada para iOS 12 para verificar si top> 24 en lugar de top> 0.
Editar: en el simulador puede ir a Hardware, Activar barra de estado de llamada entrante. Hacer eso me muestra que la altura de la barra de estado no cambia en el iPhone X en iOS 11 o iPhone XS iOS 12 cuando se realiza una llamada. Todo lo que cambia es el ícono de tiempo, que obtiene un fondo verde, en ambos casos. Aquí hay un complemento:
fuente
if _window.safeAreaInsets != UIEdgeInsets.zero
para permitir cualquier orientación del dispositivo.top
,safeAreaInsets.bottom
será 34 en iPhone X y 0 en otros dispositivosDeberá realizar diferentes detecciones de iPhone X según la necesidad real.
para tratar con la muesca superior (barra de estado, barra de navegación), etc.
para tratar con el indicador de inicio inferior (pestaña), etc.
para tamaño de fondos, funciones de pantalla completa, etc.
Nota: eventualmente mézclelo con
UIDevice.current.userInterfaceIdiom == .phone
Nota: este método requiere tener un guión gráfico de LaunchScreen o imágenes de lanzamiento adecuadas
para relación de fondos, funciones de desplazamiento, etc.
Nota: este método requiere tener un guión gráfico de LaunchScreen o imágenes de lanzamiento adecuadas
para análisis, estadísticas, seguimiento, etc.
Obtenga el identificador de la máquina y compárelo con los valores documentados:
Para incluir el simulador como un iPhone X válido en sus análisis:
Para incluir iPhone XS, XS Max y XR, simplemente busque modelos que comiencen con "iPhone11":
para soporte de faceID
fuente
return LAContext().biometryType == .typeFaceID
funcionara incluso si el usuario hubiera denegado canEvaluatePolicy, pero no funciona para mí, todavía regresa.none
model == "iPhone10,3" || model == "iPhone10,6"
), y sicanUseFaceID
devuelve falso, significa que fue rechazado por el usuario.Puede hacer esto para detectar el dispositivo iPhone X según la dimensión.
Rápido
C objetivo
pero ,
Esto no es suficiente. ¿Qué pasaría si Apple anunciara el próximo iPhone con la misma dimensión que el iPhone X? Entonces, la mejor manera es usar una cadena de hardware para detectar el dispositivo.
Para el dispositivo más nuevo, la cadena de hardware es la siguiente.
iPhone 8 - iPhone10,1 o iPhone 10,4
iPhone 8 Plus - iPhone10,2 o iPhone 10,5
iPhone X - iPhone10,3 o iPhone10,6
fuente
[UIDevice currentDevice]
lugar de[[UIDevice alloc] init]
Verifique el nombre del modelo / máquina del dispositivo , NO use el recuento de puntos / píxeles en su código directamente, es un código duro y no tiene sentido para el hardware del dispositivo , el modelo del dispositivo es el único identificador único para un tipo de dispositivo que coincida .
Resultado:
Refiérase a esta respuesta .
Implementación de código completo:
fuente
define IS_IPHONE_X (límites de IS_IPHONE && [[UIScreen mainScreen]] .size.height == 812.0)
Nota: tenga cuidado, funciona bien solo para orientación vertical
fuente
nativeScale
con3.0
, ¿verdad?Después de ver todas las respuestas, esto es lo que terminé haciendo:
Solución (compatible con Swift 4.1)
Utilizar
Nota
Pre Swift 4.1 puede verificar si la aplicación se ejecuta en un simulador de esta manera:
A partir de Swift 4.1 en adelante, puede verificar si la aplicación se está ejecutando en un simulador utilizando la condición de plataforma del entorno Target :
(el método anterior seguirá funcionando, pero este nuevo método es más a prueba de futuro)
fuente
Todas estas respuestas basadas en dimensiones son susceptibles a un comportamiento incorrecto en dispositivos futuros. Funcionarán hoy, pero ¿qué pasa si el próximo año hay un iPhone del mismo tamaño pero tiene la cámara, etc. debajo del cristal para que no haya "muesca"? Si la única opción es actualizar la aplicación, entonces es una solución pobre para usted y sus clientes.
También puede verificar la cadena del modelo de hardware como "iPhone10,1", pero eso es problemático porque a veces Apple lanza diferentes números de modelo para diferentes operadores de todo el mundo.
El enfoque correcto es rediseñar el diseño superior o resolver los problemas que tiene con la altura de la barra de navegación personalizada (eso es en lo que me enfocaría). Pero, si decide no hacer ninguna de esas cosas, tenga en cuenta que lo que sea que esté haciendo es un truco para que esto funcione hoy , y tendrá que corregirlo en algún momento, tal vez varias veces, para mantener los trucos. trabajando.
fuente
SWIFT 4+ Respuesta
iPhone X, XR, XS, XSMAX, 11 Pro, 11 Pro Max:
Nota: necesita un dispositivo real para la prueba
Referencia
fuente
Extensión reutilizable SWIFT 4/5 con soporte para iPhone 11
fuente
UIDevice.current.hasHomeButton
Sí, es posible. Descargue la extensión UIDevice-Hardware (o instálela a través de 'UIDevice-Hardware' de CocoaPod) y luego use:
Tenga en cuenta que esto no funcionará en el simulador, solo en el dispositivo real.
fuente
ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"]
en Simulator para obtener los valores reales de Xcode.Según la respuesta de @ saswanb, esta es una versión de Swift 4:
fuente
keyWindow
esnil
hasta que el controlador de vista principal ha llamadoviewDidAppear
Sé que es solo una solución Swift , pero podría ayudar a alguien.
Tengo
globals.swift
en cada proyecto y una de las cosas que siempre agrego esDeviceType
detectar fácilmente el dispositivo del usuario:Luego para usarlo:
Si lo usa
LaunchImage
en su proyecto, asegúrese de agregar imágenes para todos los dispositivos compatibles (como XS Max, XR) porqueUIScreen.main.bounds
no devolverá el valor adecuado sin ellos.fuente
if DeviceType.iPhoneX { //do something for iPhone X notch }else{ // don’t do anything about notch }
Todas las respuestas que están usando
height
son solo la mitad de la historia por una razón. Si va a verificar así cuando la orientación del dispositivo eslandscapeLeft
olandscapeRight
la verificación fallará, porqueheight
se cambia con lawidth
.Es por eso que mi solución se ve así en Swift 4.0:
fuente
No debe suponer que el único dispositivo que Apple lanzará con una altura diferente de UINavigationBar será el iPhone X. Intente resolver este problema utilizando una solución más genérica. Si desea que la barra siempre sea 20px más grande que su altura predeterminada, su código debe agregar 20px a la altura de la barra, en lugar de establecerla en 64px (44px + 20px).
fuente
fuente
Swift 3 + 4:
Ejemplo:
fuente
fuente
fuente
Por lo general, el programador lo necesita para limitar la parte superior o inferior, por lo que estos métodos pueden ayudar
Para antes del iPhone X, estos métodos regresan: 0
Para iPhone X: 44 y 34 en consecuencia
Luego solo agregue estos extras a las restricciones superiores o inferiores
fuente
Para aquellos que obtienen 2001px en lugar de 2436px para la altura de los límites nativos (como yo), es porque construiste tu aplicación con un SDK anterior, antes de iOS 11 (Xcode 8 en lugar de Xcode 9). Con un SDK anterior, iOS mostrará las aplicaciones "en caja negra" en el iPhone X en lugar de extender la pantalla de borde a borde, más allá de la "muesca del sensor" superior. Esto reduce el tamaño de la pantalla, razón por la cual esa propiedad devuelve 2001 en lugar de 2436.
La solución más simple es verificar ambos tamaños si solo está interesado en la detección de dispositivos. Utilicé este método para detectar FaceID mientras construía con un Xcode SDK anterior que no tiene el valor ENUM que especifica el tipo biométrico. En esta situación, la detección del dispositivo usando la altura de la pantalla parecía ser la mejor manera de saber si el dispositivo tenía FaceID vs TouchID sin tener que actualizar Xcode.
fuente
NO use el tamaño de píxel de la pantalla como lo han sugerido otras soluciones, esto es malo ya que puede dar lugar a falsos positivos para dispositivos futuros; no funcionará si UIWindow aún no se ha procesado (AppDelegate), no funcionará en aplicaciones horizontales y puede fallar en el simulador si se establece la escala.
En cambio, hice una macro para este propósito, es muy fácil de usar y se basa en indicadores de hardware para evitar los problemas antes mencionados.
Editar: actualizado para admitir iPhoneX, iPhone XS, iPhoneXR, iPhoneXS Max
Usar:
Sí, de verdad.
Macro:
Simplemente copie y pegue esto en cualquier lugar, prefiero la parte inferior de mi archivo .h después
@end
fuente
if (@available(iOS 11.0, *)) { [UIApplication sharedApplication].keyWindow.safeAreaInsets.top }
Expliqué tus respuestas sobre las de los demás e hice una rápida extensión en UIDevice. Me gustan las enumeraciones rápidas y "todo en orden" y atomizado. He creado una solución que funciona tanto en el dispositivo como en el simulador.
Ventajas: - interfaz simple, uso, por ejemplo
UIDevice.current.isIPhoneX
-UIDeviceModelType
enum le brinda la capacidad de extender fácilmente las características y constantes específicas del modelo que desea usar en su aplicación, por ejemplo, cornerRadiusDesventaja: es una solución específica del modelo, no específica de la resolución, por ejemplo, si Apple producirá otro modelo con las mismas especificaciones, esto no funcionará correctamente y debe agregar otro modelo para que funcione => necesita actualizar su aplicación
fuente
Mirror
, será más rápido usarlosysctlbyname
como se hizo en la respuesta Cloud9999Strife (y en mi respuesta también).Confío en la altura del marco de la barra de estado para detectar si se trata de un iPhone X:
Esto es para la aplicación un retrato. También puede verificar el tamaño de acuerdo con la orientación del dispositivo. Además, en otros iPhones, la barra de estado puede estar oculta, por lo que la altura del marco es
0
. En iPhone X, la barra de estado nunca está oculta.fuente
controller
con esto:- (BOOL)prefersStatusBarHidden { return YES; }
entonces la altura de la barra de estado es 0.Estaba usando el código de Peter Kreinz (porque estaba limpio e hizo lo que necesitaba) pero luego me di cuenta de que funciona justo cuando el dispositivo está en posición vertical (dado que el relleno superior estará en la parte superior, obviamente) Así que creé una extensión para manejar todo orientaciones con sus respectivos rellenos, sin retransmitir en el tamaño de la pantalla:
Y en su sitio de llamadas simplemente:
fuente
Alternativamente, puede consultar el pod ' DeviceKit '. Una vez instalado, todo lo que necesita hacer para verificar el dispositivo es:
fuente
Noviembre 2019:
Esto es lo que uso en todos mis proyectos de producción. Tenga en cuenta que esta esencia es bastante larga.
Funciona con simuladores 💯
Uso: let inset: CGFloat = DeviceUtility.isIphoneXType? 50.0: 40.0
fuente
Tuve que resolver el mismo problema recientemente. Y aunque esta pregunta se responde definitivamente ("No"), esto puede ayudar a otros que necesitan un comportamiento de diseño específico para iPhone X.
No estaba realmente interesado en saber si el dispositivo era iPhone X. Estaba interesado en saber si el dispositivo tenía una pantalla con muescas.
También podría escribir una
hasOnScreenHomeIndicator
variable a lo largo de las mismas líneas (aunque, tal vez, verifique el área segura inferior).Lo anterior usa mi extensión activada
UIView
para un acceso conveniente a las inserciones de área segura en iOS 10 y versiones anteriores.fuente
En Vertical solo uso el ancho y la altura del marco de la vista para verificar:
Las dimensiones de la pantalla vertical se enumeran aquí.
fuente
Hay varias razones para querer saber qué es el dispositivo.
Puede verificar la altura del dispositivo (y el ancho). Esto es útil para el diseño, pero generalmente no desea hacerlo si desea conocer el dispositivo exacto.
Para fines de diseño, también puede usar
UIView.safeAreaInsets
.Si desea mostrar el nombre del dispositivo, por ejemplo, para que se incluya en un correo electrónico con fines de diagnóstico, después de recuperar el modelo del dispositivo usando
sysctl ()
, puede usar el equivalente de este para calcular el nombre:fuente