Une interface se déforme dès que vous redimensionnez la fenêtre, utilisez iPhone Mirroring ou ouvrez une seconde scène.
La solution la plus rapide n’est pas de remplacer UIScreen.main par un autre objet global : utilisez UIWindowScene.screen pour les propriétés de l’écran, view.bounds pour la mise en page, traitCollection pour l’échelle et les traits, et effectiveGeometry uniquement pour la géométrie de scène. C’est la règle centrale pour choisir une alternative à UIScreen.main dans iOS 27.
Dernière mise à jour : 26 août 2026. Les conclusions techniques ont été vérifiées à partir de la session 278 de WWDC26 consacrée aux fenêtres redimensionnables et des documentations UIKit liées aux contextes d’écran, aux vues et aux traits. Les caractéristiques d’un éventuel iPhone pliable restent des informations non confirmées et ne servent pas de base aux recommandations ci-dessous.
Cet article s’adresse à trois profils :
- vous maintenez un projet UIKit ou hybride contenant de nombreux appels à
UIScreen.main,screen.boundsou des tests d’orientation ; - vous devez établir une règle d’architecture commune plutôt que laisser chaque équipe choisir une API différente ;
- vous êtes responsable de la validation dans Xcode 27, avec iPhone Mirroring, iPad et plusieurs fenêtres.
Le bon remplacement dépend de la donnée recherchée
Un appel comme UIScreen.main.bounds paraît compact, mais il mélange plusieurs questions. Cherchez-vous la taille d’un périphérique d’affichage, l’espace réellement accordé à une vue, la géométrie d’une fenêtre ou l’environnement graphique courant ? Ces données ne vivent pas au même niveau.
Pour auditer un ancien appel, classez d’abord son intention dans l’une de ces familles :
- Propriété du dispositif d’affichage : écran associé à la scène, échelle ou caractéristique de sortie.
- Géométrie de la scène : cadre et limites de la fenêtre gérée par
UIWindowScene. - Espace utilisable par le contenu : dimensions locales d’une vue ou d’un conteneur.
- Environnement adaptatif :
displayScale, size class et autres traits dutraitCollection.
La longueur de l’expression ne doit donc pas guider la migration. Deux lignes presque identiques peuvent exiger deux sources différentes.
| Besoin réel dans le code | Source à privilégier | Pourquoi | Risque si vous gardez UIScreen.main |
|---|---|---|---|
| Obtenir l’écran d’affichage d’une scène | windowScene.screen |
La valeur est rattachée à la scène actuelle | Résultat ambigu avec plusieurs scènes ou un écran externe |
| Dimensionner une sous-vue | view.bounds ou bounds du conteneur |
La mesure représente l’espace local attribué | Décalage entre la taille physique supposée et la place réellement disponible |
| Gérer la géométrie de la fenêtre | UIWindowScene.effectiveGeometry |
La lecture se fait au niveau de la scène | Seuils calculés sur une surface qui n’est pas celle de la fenêtre |
| Lire l’échelle pour dessiner | traitCollection.displayScale du contexte visuel |
Le rendu suit l’environnement courant | Images, textes ou caches dessinés avec une échelle inadéquate |
| Adapter l’interface | Traits de la vue ou du contrôleur | Les règles suivent l’espace et l’environnement reçus | Une orientation ou une taille d’écran devient un faux indicateur de mise en page |
Apple indique désormais que UIScreen.main n’est plus la source à employer comme raccourci universel. Consultez le statut documenté de UIScreen.main avant de décider si un appel peut rester isolé pour compatibilité. La bonne question en revue de code devient : « à quel objet cette donnée appartient-elle ? »
Contexte d’écran : scène courante contre singleton global
UIScreen.main exprime une intuition ancienne : une application aurait un écran principal unique. Cette hypothèse se fragilise dès qu’une application possède plusieurs scènes, exploite un écran externe ou apparaît dans un environnement de fenêtrage différent.
Lorsque votre logique a réellement besoin d’informations sur le dispositif d’affichage, remontez le contexte existant :
guard let scene = view.window?.windowScene else {
return
}
let screen = scene.screen
let scale = view.traitCollection.displayScale
La chaîne view → window → windowScene → screen est utile parce qu’elle répond à une question précise : quel écran est associé à cette scène ? La documentation UIWindowScene décrit ce rôle de conteneur de fenêtre et de contexte d’interface.
Cette chaîne ne peut cependant pas être forcée à n’importe quel moment. Une vue qui n’est pas encore installée dans une fenêtre ne possède pas nécessairement de windowScene. Un utilitaire appelé depuis l’initialisation d’un modèle, une extension ou une tâche de préparation hors interface n’a pas de contexte visuel fiable. Dans ce cas, trois options sont plus sûres :
- transmettre explicitement le contexte depuis le contrôleur qui le possède ;
- différer le calcul jusqu’à l’entrée de la vue dans une fenêtre ;
- supprimer la dépendance à l’écran si le code cherchait en réalité à dimensionner une vue.
Le principal avantage de windowScene.screen est sa précision. Son inconvénient est sa dépendance au cycle de vie. Vous devez donc accepter qu’une valeur ne soit pas disponible avant l’attachement de l’interface. Un guard explicite vaut mieux qu’une valeur globale silencieusement fausse.
Cas d’usage : aperçu vidéo et écran externe
Imaginez un éditeur vidéo UIKit qui dessine une zone d’aperçu et propose une sortie vers un affichage externe. Si le code utilise UIScreen.main.bounds pour choisir la résolution de son tampon, il associe la sortie à l’écran supposé principal. Si l’aperçu appartient à une fenêtre donnée, le tampon de l’aperçu doit plutôt suivre les bounds de cette vue et son displayScale. La sortie externe, elle, doit être traitée depuis le contexte de la scène qui la présente.
Le même appel historique ne possède donc pas une seule correction. La réponse dépend de la surface concernée.
Espace de mise en page : bounds locales contre géométrie de scène
Pour une interface, la taille de l’écran n’est presque jamais la bonne mesure. Une application peut recevoir une fenêtre plus étroite, une zone réduite par une barre latérale, un conteneur fractionné ou une présentation distante. La documentation de UIView.bounds rappelle que cette propriété décrit le rectangle de coordonnées de la vue, et non la surface physique complète de l’appareil.
Utilisez view.bounds lorsque vous :
- placez une piste audio dans un éditeur ;
- calculez le nombre de colonnes d’une galerie ;
- dimensionnez un canevas de design ;
- positionnez des contrôles dans un lecteur vidéo ;
- adaptez une barre d’outils à son conteneur.
Utilisez les bounds du parent lorsque la décision concerne directement le conteneur. Ne remontez pas à l’écran pour éviter de transmettre une dépendance de contexte.
UIWindowScene.effectiveGeometry répond à une autre question. Cette propriété concerne la géométrie effective de la scène, donc la fenêtre comme unité de gestion. Elle convient à une logique qui doit connaître l’espace global de la scène, pas à une sous-vue qui doit savoir combien de place son parent lui laisse. La documentation d’effectiveGeometry doit être lue avec cette distinction en tête.
Pourquoi iPhone Mirroring révèle les mauvaises hypothèses
Avec iPhone Mirroring, l’utilisateur voit et manipule une représentation de l’iPhone depuis le Mac. Les conditions d’utilisation et les limites de cette fonction sont précisées par Apple Support. Pour le développeur, l’enseignement est simple : la surface visible et l’espace attribué à la présentation ne doivent pas être déduits d’un écran physique supposé.
Une interface qui divise la largeur de UIScreen.main.bounds peut sembler correcte sur un appareil réel, puis produire des contrôles trop grands ou trop petits dans une fenêtre miroir. La correction consiste à laisser le système fournir la taille du conteneur et à recalculer la mise en page lorsque les bounds ou les traits changent.
Pour une application de création audio ou vidéo, cette règle est particulièrement importante. Une timeline doit suivre la largeur de son propre viewport. Un cache de miniature doit suivre l’échelle du contexte de rendu. Une fenêtre d’outils ne doit pas reprendre la taille de l’écran complet pour décider si ses boutons tiennent sur une ligne.
Échelle, traits et orientation : trois décisions séparées
La migration devient fragile lorsque le code utilise une seule valeur pour trois décisions : dessiner, organiser et orienter. Ces responsabilités doivent être séparées.
Échelle de rendu
Si vous calculez la taille d’un bitmap, d’un CALayer ou d’un cache de dessin, partez du traitCollection du contexte qui rend effectivement la surface. Le trait displayScale est alors attaché à la vue, au contrôleur ou à l’environnement approprié, plutôt qu’à un écran global.
let displayScale = view.traitCollection.displayScale
let pixelWidth = Int(view.bounds.width * displayScale)
Cet exemple ne dit pas « prenez la taille de l’écran puis adaptez-la ». Il dit « créez une surface de pixels correspondant à cette vue ». Si le code dessine pour une autre vue, utilisez le trait de cette autre vue. Ne partagez pas automatiquement une valeur calculée au démarrage de l’application.
Taille adaptative
Une size class n’est pas une mesure exacte. Elle sert à exprimer un environnement compact ou régulier et à choisir une composition générale. Pour connaître la place précise d’un panneau, utilisez ses bounds. Pour savoir si un contrôleur doit présenter une navigation différente, utilisez ses traits et son environnement de transition. Apple décrit cette adaptation dans le guide Adapting your app when traits change.
Une erreur fréquente consiste à remplacer :
if UIScreen.main.bounds.width < threshold {
showCompactLayout()
}
par une autre lecture globale de largeur. Vous avez simplement déplacé le problème. La version correcte dépend du niveau de décision :
if view.bounds.width < threshold {
showCompactLayout()
}
ou, lorsque la règle est qualitative, d’un changement de traits. Le seuil lui-même doit appartenir au composant concerné, pas à une constante globale censée décrire tous les écrans.
Orientation
L’orientation ne doit plus être le raccourci d’une règle de mise en page. Une fenêtre peut être étroite alors que le périphérique est tenu dans une orientation qui ne correspond pas à votre hypothèse. À l’inverse, une fenêtre large peut coexister avec un appareil physiquement orienté autrement.
Conservez l’orientation pour une vraie décision d’orientation : rotation d’un outil de capture, comportement d’un jeu ou orientation d’une sortie vidéo. Pour afficher deux panneaux au lieu d’un seul, mesurez l’espace reçu par le conteneur. Cette séparation évite de casser les interfaces redimensionnables annoncées dans le contexte de WWDC26 Session 278.
Coût de migration : quatre catégories de risque
Ne traitez pas tous les appels à UIScreen.main avec le même correctif. Une revue rapide peut les ranger dans quatre catégories.
Remplacement local. Le code a déjà accès à une vue ou à un contrôleur et cherche seulement son échelle ou ses bounds. La correction reste proche de l’appel d’origine. Le risque principal est de vérifier que le calcul intervient après l’attachement à la fenêtre.
Remontée au niveau scène. Le code gère une fenêtre, une connexion à un écran ou une politique de scène. Il faut faire passer UIWindowScene dans cette couche. Le risque est architectural : un service ancien, conçu comme singleton, doit désormais recevoir un contexte.
Descente au niveau vue. Le code situé dans un gestionnaire global calcule la taille d’un composant visuel. Déplacez la décision vers le composant ou son conteneur. Le bénéfice est une meilleure réutilisation, mais plusieurs signatures peuvent changer.
Refonte de la règle métier. Le code utilise largeur d’écran, orientation ou résolution comme proxy d’une décision produit : afficher un panneau, activer un mode avancé ou réduire une barre d’outils. Il ne suffit pas de changer l’API. Il faut reformuler la règle avec la capacité réelle du conteneur, les traits ou un état explicitement transmis.
Pour les anciens systèmes, encapsulez l’accès dans un objet de contexte compatible avec vos versions prises en charge. Cette enveloppe doit exposer une intention, par exemple currentDisplayScale ou contentBounds, et non reproduire un nouveau singleton d’écran. Vous pourrez alors faire évoluer l’implémentation sans répandre les vérifications de disponibilité dans toute la base de code.
En revue, refusez une modification si son auteur ne peut pas répondre à ces questions :
- cette valeur appartient-elle à une scène, une fenêtre, une vue ou un trait ?
- que se passe-t-il avant l’attachement de la vue ?
- la valeur change-t-elle lorsque la fenêtre est redimensionnée ?
- une seconde scène peut-elle recevoir une valeur différente ?
- le calcul sert-il à dessiner, à composer l’interface ou à décider d’un comportement métier ?
FAQ de migration ciblée
Les questions ci-dessous couvrent les cas que les équipes rencontrent généralement en préparant leur passage à iOS 27.
iOS 27 et l’accès à l’écran
Il n’y a pas de substitution mécanique. Si vous avez besoin de l’écran d’une scène, utilisez windowScene.screen. Si votre code veut connaître l’espace de présentation, cette API est déjà trop éloignée de l’intention : partez de view.bounds ou du conteneur. Cette règle évite de transformer une migration de dépréciation en simple changement de nom.
effectiveGeometry ou view.bounds
La distinction est hiérarchique. effectiveGeometry sert à raisonner sur la scène et sa fenêtre. view.bounds sert à raisonner sur la surface locale d’une vue. Pour un panneau, une timeline ou un canevas, utilisez la vue. Pour une politique qui concerne la fenêtre entière, utilisez la scène. Si vous mélangez les deux, vos seuils deviennent difficiles à expliquer et à tester.
displayScale avec iPhone Mirroring
Le rendu doit suivre le contexte de la vue qui dessine. Lisez donc view.traitCollection.displayScale, ou le trait du contrôleur responsable de la surface. Ne déduisez pas cette valeur de UIScreen.main, du Mac hôte ou d’une dimension physique supposée. Le miroir est précisément un cas où l’environnement de présentation peut contredire l’hypothèse historique d’un écran unique.
Conservation temporaire dans un ancien projet
Une conservation provisoire est défendable si elle est documentée, isolée et limitée à une donnée réellement liée à l’écran. Elle ne doit pas rester dans les calculs de layout, les caches de rendu ou les tests d’orientation. Ajoutez un commentaire indiquant la scène attendue, puis créez un ticket de migration. Sans cette limite, le compromis devient la nouvelle architecture.
Vérification dans Xcode 27
Dans Xcode 27, ne validez pas uniquement le lancement et l’absence d’avertissement. Faites varier la taille de la fenêtre, exécutez le même parcours dans iPhone Mirroring, ouvrez l’interface sur iPad et contrôlez les appareils réels retenus par votre produit. Inspectez les contraintes, les caches d’images, les coordonnées de pointeurs ou de gestes et les transitions de traits. La forme visuelle n’est qu’un des résultats à vérifier.
Checklist de validation avant fusion
Utilisez cette liste sur chaque groupe d’appels migré. Elle est volontairement orientée décision, pas seulement compilation.
- [ ] Chaque occurrence de
UIScreen.maina été classée : écran, scène, vue, trait ou règle métier. - [ ] Les propriétés d’affichage sont obtenues depuis la
UIWindowSceneréellement concernée. - [ ] Les calculs de layout utilisent les bounds de la vue ou du conteneur qui reçoit effectivement le contenu.
- [ ]
effectiveGeometryn’est utilisé que par une logique qui gère la scène ou la fenêtre. - [ ]
displayScaleprovient dutraitCollectiondu contexte qui dessine. - [ ] Une size class n’est pas utilisée comme mesure exacte de largeur ou de hauteur.
- [ ] L’orientation ne décide plus seule d’un layout compact ou large.
- [ ] Les appels effectués avant l’entrée dans une fenêtre ont un comportement explicite lorsque le contexte est absent.
- [ ] Le code peut expliquer à quelle scène appartient chaque valeur mise en cache.
- [ ] Le test de redimensionnement dans Xcode 27 couvre au moins une fenêtre étroite, une fenêtre large et une transition entre les deux.
- [ ] iPhone Mirroring est inclus lorsque l’application prend en charge ce parcours.
- [ ] Les scénarios iPad et les appareils réels pertinents vérifient séparément layout, échelle, dessin et coordonnées d’interaction.
- [ ] Les anciens systèmes pris en charge passent par une enveloppe de contexte plutôt que par un nouvel accès global.
- [ ] La revue de code contient un exemple de cas où
view.boundsest correct et un autre oùwindowScene.screenest nécessaire.
Cette liste ne remplace pas les tests fonctionnels. Elle donne toutefois un critère d’acceptation reproductible : chaque appel doit avoir un propriétaire de donnée identifiable.
Stratégie de test : poste unique contre environnement Mac parallèle
Un seul Mac de développement peut suffire pour une vérification locale rapide. Il devient moins convaincant lorsque le même poste doit faire tourner Xcode 27, des simulateurs, iPhone Mirroring, un parcours iPad et une suite CI. Les files d’attente s’allongent, les versions d’outils se mélangent et la reproduction d’une fenêtre précise dépend parfois d’un état local non documenté.
Un environnement Mac parallèle apporte une séparation utile :
- une machine peut rester dédiée au développement interactif ;
- une autre peut exécuter les régressions de fenêtres et de traits ;
- les scripts peuvent repartir d’un environnement décrit plutôt que d’un poste modifié au fil des essais ;
- un défaut lié à une taille de fenêtre ou à un cache graphique peut être rejoué sans interrompre le travail courant.
Cela ne signifie pas que la location convient à tous les projets. Un produit soumis à une charge soutenue et stable peut avoir intérêt à acheter et administrer son propre parc. Une équipe qui dépend d’un périphérique physique spécifique doit également vérifier que l’environnement choisi l’expose réellement. En revanche, pour une migration ponctuelle ou une période de validation serrée, la capacité à isoler les essais peut compter davantage que la possession permanente du matériel.
Avant de réserver une ressource, définissez votre matrice : version de Xcode 27, type de simulation, parcours iPhone Mirroring, fenêtres iPad, accès aux scripts CI et méthode de collecte des artefacts. La console MacHTML peut ensuite servir à vérifier les ressources effectivement disponibles, tandis que la documentation d’aide MacHTML permet de clarifier le fonctionnement de la livraison et de l’accès. Ne déduisez pas d’une fiche générale une capacité qui n’a pas été vérifiée pour votre scénario.
Décision finale : corriger le contexte avant de corriger l’API
Si votre solution actuelle repose sur un seul Mac, une seule taille d’appareil et une exécution séquentielle, ses limites sont concrètes : elle masque les effets multi-scène, elle laisse peu de place aux essais simultanés et elle rend les défauts de fenêtre plus difficiles à reproduire. Ajouter des remplacements globaux de UIScreen.main ne résout aucun de ces problèmes ; cela déplace seulement l’incertitude.
Commencez par appliquer la matrice de sémantique et la checklist à votre code. Si votre parc Mac ne peut pas couvrir en parallèle Xcode 27, iPhone Mirroring et les parcours iPad, une location MacHTML peut fournir un environnement de validation temporaire plus adapté qu’un poste local surchargé. Elle est moins pertinente pour un besoin permanent de calcul lourd ou pour des tests exigeant des interfaces physiques particulières. Le bon choix dépend donc de votre échéance, de votre matrice de test et du contexte matériel réellement requis.
Pour aller plus loin: Tester les API de mise en page et les fenêtres redimensionnables avec les bêtas développeur d’iOS 27 Distinguer les limites du simulateur et valider les comportements d’interface sur un appareil iOS 27 Configurer un environnement Xcode distant pour vérifier les interfaces iOS sans simulateur ralenti
Validez votre migration iOS sur un Mac distant
Accédez à un environnement MacHTML à distance pour compiler et tester vos interfaces UIKit dans des conditions réelles. Vérifiez le comportement de vos fenêtres redimensionnables, de vos orientations et de vos mises en page avec une configuration maîtrisée. Travaillez depuis votre navigateur grâce à un accès distant conçu pour les projets de développement et de validation iOS. Choisissez l’offre MacHTML adaptée à vos besoins et fiabilisez votre transition au-delà de UIScreen.main.