Mon application iOS utilise une hauteur personnalisée pour UINavigationBar
qui entraîne des problèmes sur le nouvel iPhone X.
Quelqu'un sait-il déjà comment détecter de manière fiable par programme (dans Objective-C) si une application fonctionne sur iPhone X?
ÉDITER:
Bien sûr, la vérification de la taille de l'écran est possible, cependant, je me demande s'il existe une méthode "build in" comme TARGET_OS_IPHONE
pour détecter iOS ...
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if (screenSize.height == 812)
NSLog(@"iPhone X");
}
EDIT 2:
Je ne pense pas que ma question soit un double de la question liée. Bien sûr, il existe des méthodes pour «mesurer» les différentes propriétés de l'appareil actuel et utiliser les résultats pour décider quel appareil est utilisé. Cependant, ce n'était pas le point réel de ma question comme j'ai essayé de le souligner dans mon premier montage.
La vraie question est: "Est-il possible de détecter directement si l'appareil actuel est un iPhone X (par exemple par une fonction SDK) ou dois-je utiliser des mesures indirectes" ?
D'après les réponses données jusqu'à présent, je suppose que la réponse est "Non, il n'y a pas de méthode directe. Les mesures sont la voie à suivre".
la source
Réponses:
Sur la base de votre question, la réponse est non. Il n'y a pas de méthode directe. Pour plus d'informations, vous pouvez obtenir les informations ici:
et
La hauteur de l'iPhone X est de 2436 px
À partir des tailles et résolutions d'écran de l'appareil :
À partir des tailles d'écran et des orientations de l'appareil :
Swift 3 et versions ultérieures :
Objectif-C :
Xamarin.iOS :
Basé sur votre question comme suit:
Ou utilisez
screenSize.height
comme flotteur812.0f
non int812
.Pour plus d'informations, vous pouvez consulter la page suivante dans les instructions relatives à l'interface humaine iOS:
Rapide :
Détecter avec
topNotch
:Objectif-C :
MISE À JOUR :
N'utilisez pas la
userInterfaceIdiom
propriété pour identifier le type de périphérique, comme l' explique la documentation de userInterfaceIdiom :Autrement dit, cette propriété est simplement utilisée pour identifier le style d'affichage de l'application en cours d'exécution. Cependant, l'application iPhone (pas la version universelle) pourrait être installée sur l'appareil iPad via l'App Store, dans ce cas,
userInterfaceIdiom
leUIUserInterfaceIdiomPhone
également.La bonne façon est d'obtenir le nom de la machine via
uname
. Vérifiez les éléments suivants pour plus de détails:la source
userInterfaceIdiom
retourneraUIUserInterfaceIdiomPhone
également. Cette réponse est fausse.Autre possibilité, qui fonctionne sur iOS 11 et iOS 12 car l'iPhone X est le seul avec une encoche en haut et un encart de 44. C'est ce que je détecte vraiment ici:
Objectif c:
Swift 4:
Et bien sûr, vous devrez peut-être vérifier les encarts de zone de sécurité gauche et droite si vous êtes en orientation paysage.
Edit: _window est la UIWindow de l'AppDelegate, où cette vérification est effectuée dans l'application didFinishLaunchingWithOptions.
Réponse mise à jour pour iOS 12 pour vérifier si top> 24 plutôt que top> 0.
Modifier: dans le simulateur, vous pouvez aller dans Matériel, Basculer la barre d'état en cours d'appel. Cela me montre que la hauteur de la barre d'état ne change pas sur iPhone X sur iOS 11 ou iPhone XS iOS 12 lors d'un appel. Tout ce qui change, c'est l'icône de l'heure, qui devient verte dans les deux cas. Voici un instantané:
la source
if _window.safeAreaInsets != UIEdgeInsets.zero
pour permettre l'orientation de n'importe quel appareil.top
,safeAreaInsets.bottom
sera 34 sur iPhone X et 0 sur d'autres appareilsVous devez effectuer différentes détections de l'iPhone X en fonction des besoins réels.
pour gérer le top (barre d'état, barre de navigation), etc.
pour gérer l'indicateur d'accueil inférieur (barre de tabulation), etc.
pour la taille des arrière-plans, les fonctionnalités plein écran, etc.
Remarque: éventuellement mélanger avec
UIDevice.current.userInterfaceIdiom == .phone
Note: cette méthode nécessite d'avoir un storyboard LaunchScreen ou des LaunchImages appropriés
pour le taux d'arrière-plan, les fonctions de défilement, etc.
Remarque: cette méthode nécessite d'avoir un storyboard LaunchScreen ou des LaunchImages appropriés
pour l'analyse, les statistiques, le suivi, etc.
Obtenez l'identifiant de la machine et comparez-le aux valeurs documentées:
Pour inclure le simulateur en tant qu'iPhone X valide dans vos analyses:
Pour inclure l'iPhone XS, XS Max et XR, recherchez simplement les modèles commençant par «iPhone11»:
pour le support faceID
la source
return LAContext().biometryType == .typeFaceID
cela fonctionnerait même si l'utilisateur avait refusé canEvaluatePolicy, mais cela ne fonctionne pas pour moi, il revient toujours.none
model == "iPhone10,3" || model == "iPhone10,6"
), et sicanUseFaceID
renvoie faux, cela signifie qu'il a été refusé par l'utilisateur.Vous pouvez faire comme cela pour détecter un appareil iPhone X selon sa dimension.
Rapide
Objectif c
Mais ,
Ce n'est pas un moyen suffisant. Et si Apple annonçait le prochain iPhone avec la même dimension que l'iPhone X. La meilleure façon est donc d'utiliser la chaîne Hardware pour détecter l'appareil.
Pour les appareils plus récents, la chaîne matérielle est la suivante.
iPhone 8 - iPhone10,1 ou iPhone 10,4
iPhone 8 Plus - iPhone10,2 ou iPhone 10,5
iPhone X - iPhone10,3 ou iPhone10,6
la source
[UIDevice currentDevice]
place de[[UIDevice alloc] init]
Vérifiez le modèle de l'appareil / le nom de la machine , N'utilisez PAS directement le nombre de points / pixels dans votre code, c'est un code dur et n'a pas de sens pour le matériel de l'appareil, le modèle de l'appareil est le seul identifiant unique pour un type d'appareil à faire correspondre .
Résultat:
Se référer à cette réponse .
Implémentation complète du code:
la source
définir IS_IPHONE_X (limites IS_IPHONE && [[UIScreen mainScreen]] .size.height == 812.0)
Remarque: - Attention, cela fonctionne très bien uniquement pour l'orientation portrait
la source
nativeScale
avec3.0
, non?Après avoir regardé toutes les réponses, voici ce que j'ai fini par faire:
Solution (compatible Swift 4.1)
Utilisation
Remarque
Avant Swift 4.1, vous pouvez vérifier si l'application fonctionne sur un simulateur comme celui-ci:
À partir de Swift 4.1 et versions ultérieures, vous pouvez vérifier si l'application s'exécute sur un simulateur à l'aide de la condition de plate-forme d'environnement cible :
(l'ancienne méthode fonctionnera toujours, mais cette nouvelle méthode est plus à l'épreuve du temps)
la source
Toutes ces réponses basées sur les dimensions sont susceptibles d'un comportement incorrect sur les futurs appareils. Ils fonctionneront aujourd'hui, mais que se passera-t-il s'il y a un iPhone l'année prochaine de la même taille mais avec l'appareil photo, etc. sous la vitre, donc il n'y a pas de "cran?" Si la seule option est de mettre à jour l'application, c'est une mauvaise solution pour vous et vos clients.
Vous pouvez également vérifier la chaîne du modèle matériel comme "iPhone10,1", mais cela pose problème car parfois Apple publie des numéros de modèle différents pour différents opérateurs à travers le monde.
L'approche correcte consiste à repenser la disposition supérieure ou à résoudre les problèmes que vous rencontrez avec la hauteur de la barre de navigation personnalisée (c'est ce sur quoi je me concentrerais). Mais, si vous décidez de ne faire aucune de ces choses, sachez que tout ce que vous faites est un hack pour que cela fonctionne aujourd'hui , et vous devrez le corriger à un moment donné, peut-être plusieurs fois, pour garder les hacks travail.
la source
Réponse de SWIFT 4+
iPhone X, XR, XS, XSMAX, 11 Pro, 11 Pro Max:
Remarque: besoin d'un véritable appareil pour le test
Référence
la source
SWIFT 4/5 réutilisable l' extension avec l' iPhone 11 support
la source
UIDevice.current.hasHomeButton
Oui c'est possible. Téléchargez l' extension UIDevice-Hardware (ou installez-la via CocoaPod 'UIDevice-Hardware') puis utilisez:
Notez que cela ne fonctionnera pas dans le simulateur, uniquement sur le périphérique réel.
la source
ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"]
dans Simulator pour obtenir les valeurs réelles de Xcode.Selon la réponse de @ saswanb, il s'agit d'une version Swift 4:
la source
keyWindow
estnil
jusqu'à ce que le contrôleur principal de vue a appeléviewDidAppear
Je sais que ce n'est qu'un Swift solution , mais cela pourrait aider quelqu'un.
J'ai
globals.swift
dans chaque projet et l'une des choses que j'ajoute toujours estDeviceType
de détecter facilement l'appareil de l'utilisateur:Ensuite pour l'utiliser:
Si vous utilisez
LaunchImage
dans votre projet, assurez-vous d'ajouter des images pour tous les appareils pris en charge (comme XS Max, XR) carUIScreen.main.bounds
ils ne retourneront pas la valeur appropriée sans ceux-ci.la source
if DeviceType.iPhoneX { //do something for iPhone X notch }else{ // don’t do anything about notch }
Toutes les réponses qui utilisent le
height
sont seulement la moitié de l'histoire pour une raison. Si vous allez vérifier comme ça quand l'orientation de l'appareil estlandscapeLeft
oulandscapeRight
la vérification échouera, car leheight
est échangé avec lewidth
.C'est pourquoi ma solution ressemble à ceci dans Swift 4.0:
la source
Vous ne devez pas supposer que le seul appareil qu'Apple publie avec une hauteur UINavigationBar différente sera l'iPhone X. Essayez de résoudre ce problème en utilisant une solution plus générique. Si vous souhaitez que la barre soit toujours 20px plus grande que sa hauteur par défaut, votre code doit ajouter 20px à la hauteur de la barre, au lieu de la définir sur 64px (44px + 20px).
la source
la source
Swift 3 + 4:
Exemple:
la source
la source
la source
Habituellement, le programmeur en a besoin pour contraindre en haut ou en bas, donc ces méthodes peuvent aider
Pour avant iPhone X, ces méthodes renvoient: 0
Pour iPhone X: 44 et 34 en conséquence
Ensuite, ajoutez simplement ces extras aux contraintes supérieures ou inférieures
la source
Pour ceux qui obtiennent 2001px au lieu de 2436px pour la hauteur des limites natives (comme moi), c'est parce que vous avez construit votre application avec un SDK plus ancien, avant iOS 11 (Xcode 8 au lieu de Xcode 9). Avec un SDK plus ancien, iOS affichera les applications "en boîte noire" sur l'iPhone X au lieu d'étendre l'écran bord à bord, au-delà du "cran du capteur" supérieur. Cela réduit la taille de l'écran, c'est pourquoi cette propriété renvoie 2001 au lieu de 2436.
La solution la plus simple consiste à simplement vérifier les deux tailles si vous êtes uniquement intéressé par la détection des appareils. J'ai utilisé cette méthode pour détecter FaceID lors de la construction avec un SDK Xcode plus ancien qui n'a pas la valeur ENUM spécifiant le type biométrique. Dans cette situation, la détection de l'appareil en utilisant la hauteur de l'écran semblait être le meilleur moyen de savoir si l'appareil avait FaceID vs TouchID sans avoir à mettre à jour Xcode.
la source
N'utilisez PAS la taille des pixels de l'écran comme d'autres solutions l'ont suggéré, c'est mauvais car cela peut entraîner des faux positifs pour les futurs appareils; ne fonctionnera pas si UIWindow n'a pas encore été rendu (AppDelegate), ne fonctionnera pas dans les applications de paysage et peut échouer sur le simulateur si l'échelle est définie.
J'ai, à la place, créé une macro à cet effet, elle est très facile à utiliser et s'appuie sur des indicateurs matériels pour éviter les problèmes susmentionnés.
Modifier: mis à jour pour prendre en charge iPhoneX, iPhone XS, iPhoneXR, iPhoneXS Max
Utiliser:
Ouais, vraiment.
Macro:
Copiez-collez cela n'importe où, je préfère le bas de mon fichier .h après
@end
la source
if (@available(iOS 11.0, *)) { [UIApplication sharedApplication].keyWindow.safeAreaInsets.top }
J'ai développé vos réponses sur les autres et fait une extension rapide sur UIDevice. J'aime les énumérations rapides et "tout en ordre" et atomisé. J'ai créé une solution qui fonctionne à la fois sur l'appareil et le simulateur.
Avantages: - interface simple, utilisation par exemple
UIDevice.current.isIPhoneX
-UIDeviceModelType
enum vous donne la possibilité d'étendre facilement les fonctionnalités et les constantes spécifiques au modèle que vous souhaitez utiliser dans votre application, par exemple cornerRadiusInconvénient: - c'est une solution spécifique au modèle, pas une résolution spécifique - par exemple, si Apple produira un autre modèle avec les mêmes spécifications, cela ne fonctionnera pas correctement et vous devez ajouter un autre modèle pour que cela fonctionne => vous devez mettre à jour votre app.
la source
Mirror
, il sera plus rapide à utilisersysctlbyname
comme cela est fait dans la réponse Cloud9999Strife (et dans ma réponse aussi).Je compte sur la hauteur du cadre de la barre d'état pour détecter s'il s'agit d'un iPhone X:
C'est pour l'application un portrait. Vous pouvez également vérifier la taille en fonction de l'orientation de l'appareil. De plus, sur d'autres iPhones, la barre d'état peut être masquée, la hauteur du cadre est donc
0
. Sur iPhone X, la barre d'état n'est jamais masquée.la source
controller
avec ceci:- (BOOL)prefersStatusBarHidden { return YES; }
la hauteur de la barre d'état est alors de 0.J'utilisais le code de Peter Kreinz (car il était propre et a fait ce que je avais besoin) mais je l' ai réalisé fonctionne lorsque l'appareil est en mode portrait (depuis padding haut sera sur le dessus, évidemment) Je créé une extension pour gérer toutes les orientations avec ses rembourrages respectifs, sans relayer sur la taille de l'écran:
Et sur votre site d'appel, vous venez de:
la source
Alternativement, vous pouvez consulter le module « DeviceKit ». Une fois installé, tout ce que vous devez faire pour vérifier l'appareil est:
la source
Nov 2019:
Voici ce que j'utilise dans tous mes projets de production. Notez que cet essentiel est assez long.
Fonctionne avec des simulateurs 💯
Utilisation: laissez l'encart: CGFloat = DeviceUtility.isIphoneXType? 50,0: 40,0
la source
J'ai dû résoudre le même problème récemment. Et bien que cette question ait une réponse définitive («Non»), cela peut aider ceux qui ont besoin d'un comportement de mise en page spécifique à l'iPhone X.
Je n'étais pas vraiment intéressé à savoir si l'appareil était iPhone X. Je voulais savoir si l'appareil avait un écran cranté.
Vous pouvez également écrire un
hasOnScreenHomeIndicator
variable dans le même sens (bien que vérifier la zone de sécurité inférieure, peut-être?).Ce qui précède utilise mon extension
UIView
pour un accès pratique aux encarts de zone de sécurité sur iOS 10 et versions antérieures.la source
Dans Portrait uniquement, j'utilise la largeur et la hauteur du cadre de la vue pour vérifier:
Les dimensions de l'écran portrait sont répertoriées ici
la source
Il y a plusieurs raisons de vouloir savoir ce qu'est l'appareil.
Vous pouvez vérifier la hauteur (et la largeur) de l'appareil. Ceci est utile pour la mise en page, mais vous ne voulez généralement pas le faire si vous voulez connaître le périphérique exact.
À des fins de mise en page, vous pouvez également utiliser
UIView.safeAreaInsets
.Si vous souhaitez afficher le nom du périphérique, par exemple, à inclure dans un e-mail à des fins de diagnostic, après avoir récupéré le modèle de périphérique à l'aide
sysctl ()
, vous pouvez utiliser l'équivalent de celui-ci pour comprendre le nom:la source