Développeurs
Size classes sur iPhone Duo : plié, entrouvert et ouvert
Les size classes de l'iPhone Duo plié, entrouvert et ouvert, pourquoi s'adapter aux size classes plutôt qu'à l'orientation, avec du code SwiftUI et UIKit.
Par la rédaction AppleDuoPublié le 8 min de lecture
Sur cette page
- Quelles size classes l'iPhone Duo renvoie-t-il dans chaque posture ?
- Pourquoi utiliser les size classes plutôt que l'orientation sur iPhone Duo ?
- Comment lire les size classes en SwiftUI ?
- Comment lire les size classes en UIKit avec traitCollection ?
- Comment fonctionnent les size classes dans les panneaux d'ArrangementView ?
- Comment tester les postures de l'iPhone Duo dans Xcode Device Hub ?
- Ce qu'il faut retenir
Si vous n'avez le temps de faire qu'un seul changement avant que votre app ne rencontre l'iPhone Duo, que ce soit les size classes. L'appareil a deux écrans et plusieurs postures, et chaque posture donne à votre app un espace différent. Maîtriser les size classes de l'iPhone Duo, c'est ce qui permet à une seule mise en page de fonctionner partout, sans le moindre test sur le modèle d'appareil.
La version courte vient du développeur iOS @sarunw : plié, l'iPhone Duo est un iPhone ; déplié, c'est un iPad. Cet article explique ce que cela implique pour chaque posture, pourquoi l'orientation est le mauvais signal, et comment lire les size classes en SwiftUI et en UIKit. Tout ce qui suit s'appuie sur les Tech Talks d'Apple, les forums développeurs d'Apple et des retours de développeurs cités. Les API sont livrées avec iOS 27.1 et Xcode 27.1, et certains détails peuvent changer d'une version à l'autre.
Quelles size classes l'iPhone Duo renvoie-t-il dans chaque posture ?
Une size class est une description grossière de l'espace dont dispose votre app : compact ou regular, horizontalement et verticalement. Sur iPhone Duo, la combinaison dépend de l'écran actif, qui dépend lui-même du degré d'ouverture de l'appareil.
Dans le Tech Talk d'Apple Prepare your app for iPhone Duo, l'écran extérieur « se comporte comme les autres modèles d'iPhone », et l'écran intérieur renvoie regular dans les deux sens, ce qui laisse de la place pour du contenu comme des barres latérales. Le récapitulatif de @sarunw ajoute la posture entrouverte et les deux orientations :
| Posture | Écran | Horizontal | Vertical | Se comporte comme |
|---|---|---|---|---|
| Fermé, portrait | Extérieur | Compact | Regular | Un iPhone en portrait |
| Fermé, paysage | Extérieur | Compact | Compact | Un iPhone en paysage |
| Entrouvert, comme un livre | Intérieur | Regular | Regular | Un iPad |
| Ouvert, portrait | Intérieur | Regular | Regular | Un iPad |
| Ouvert, paysage | Intérieur | Regular | Regular | Un iPad |
Un mot sur le vocabulaire : @sarunw emploie « folded » (plié) au sens de fermé. Les Tech Talks d'Apple parlent de « partially folded, like a book » (partiellement plié, comme un livre) pour la posture entrouverte. Dans cet article, « fermé » signifie que l'écran extérieur est utilisé, et « entrouvert » que l'écran intérieur est plié au niveau de la charnière.
Pour donner un ordre de grandeur, Pasquale Pillitteri indique un écran extérieur de 466 × 678 points et un écran intérieur de 626 × 890 points en portrait. Vous ne devez pas coder en fonction de ces chiffres, mais ils expliquent pourquoi l'écran intérieur obtient une largeur regular : il est plus large que n'importe quel iPhone en portrait.
Pourquoi utiliser les size classes plutôt que l'orientation sur iPhone Duo ?
L'orientation servait autrefois de raccourci correct pour savoir s'il y avait de la place pour une deuxième colonne. Sur iPhone Duo, ce n'est plus le cas. Les recommandations d'Apple sont claires : évitez de tester l'orientation pour la mise en page et utilisez plutôt les size classes. Deux faits rendent l'orientation peu fiable ici.
- L'écran intérieur ignore vos orientations prises en charge. Apple indique que l'écran intérieur ne respecte pas les orientations d'interface prises en charge par votre app. Si vous avez verrouillé l'app en portrait et que votre code dépend de l'orientation, vous obtiendrez des mises en page que vous n'aviez jamais prévues.
- Les deux orientations sont regular sur l'écran intérieur. Portrait et paysage renvoient les mêmes size classes sur l'écran intérieur : un test d'orientation ne vous dit donc rien sur la largeur disponible.
Les réponses d'Apple sur les forums disent la même chose des tests sur l'appareil. Dans un fil, un ingénieur DTS conseille : « ne raisonnez pas en fonction d'un écran précis, mais seulement de l'espace dont vous disposez pour votre mise en page ». Dans un autre, un evangelist d'Apple recommande d'éviter la logique spécifique à un appareil, d'adopter les size classes et de prendre en charge toutes les orientations. Cela vaut aussi pour les apps iPhone qu'iOS 27 peut désormais redimensionner sur iPad et dans la recopie de l'iPhone sur Mac.
Il n'existe pas non plus de trait dédié à la posture. À la question de savoir si UITraitCollection expose le pli, un ingénieur Apple a répondu dans le fil 848007 qu'il n'existe pas de traits UITraitCollection du type mentionné. Les size classes pilotent la mise en page. Les reserved regions et les API de charnière gèrent le pli lui-même.
Comment lire les size classes en SwiftUI ?
SwiftUI place les deux size classes dans l'environnement. Lisez-les dans la vue qui prend la décision de mise en page, et SwiftUI redessine cette vue quand l'appareil s'ouvre, se ferme ou pivote. Les clés d'environnement sont celles qu'Apple montre dans le Tech Talk.
struct LibraryView: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@Environment(\.verticalSizeClass) private var verticalSizeClass
var body: some View {
if horizontalSizeClass == .regular {
// Écran intérieur : de la place pour une liste et un détail côte à côte.
HStack(spacing: 0) {
AlbumList()
AlbumDetail()
}
} else {
// Écran extérieur : une seule colonne, comme sur n'importe quel iPhone.
AlbumList()
}
}
}
Cet exemple passe d'une mise en page à une colonne à une mise en page à deux colonnes en se basant uniquement sur la largeur. Utilisez la size class verticale pour les décisions liées à la hauteur, par exemple masquer un grand en-tête quand l'écran extérieur est en paysage et que les deux valeurs sont compact.
Avant d'écrire cela à la main, vérifiez si un conteneur système ne le fait pas déjà. Apple indique que NavigationSplitView se réduit à une seule pile quand l'appareil est fermé et dispose ses colonnes côte à côte ou en superposition quand il est ouvert, et que TabView s'adapte à toutes les postures. Si votre app utilise ces conteneurs, une grande partie du travail sur les size classes est déjà faite.
Comment lire les size classes en UIKit avec traitCollection ?
En UIKit, les size classes se trouvent dans la trait collection de chaque vue et de chaque view controller : traitCollection.horizontalSizeClass et traitCollection.verticalSizeClass. Depuis iOS 17, vous pouvez vous abonner aux changements de traits au lieu de surcharger traitCollectionDidChange(_:), désormais obsolète.
final class LibraryViewController: UIViewController {
private let detailContainer = UIView()
private var listWidthConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
registerForTraitChanges(
[UITraitHorizontalSizeClass.self, UITraitVerticalSizeClass.self]
) { (self: Self, _: UITraitCollection) in
self.updateLayout()
}
updateLayout()
}
private func updateLayout() {
let isWide = traitCollection.horizontalSizeClass == .regular
detailContainer.isHidden = !isWide
listWidthConstraint.isActive = isWide
}
}
Ici, le contrôleur n'affiche son conteneur de détail que lorsque la largeur est regular, et se met à jour à chaque changement de l'une ou l'autre size class, par exemple à l'ouverture de l'appareil. Comme en SwiftUI, préférez UISplitViewController et UITabBarController quand ils conviennent, puisqu'Apple indique qu'ils s'adaptent automatiquement au pli.
Deux habitudes complémentaires issues du même Tech Talk aident les mises en page basées sur les size classes à bien se comporter. Remplacez UIScreen.main.scale par traitCollection.displayScale, car l'« écran principal » est une notion ambiguë sur un appareil à deux écrans. Et traitez les marges de safe area de chaque côté indépendamment, car sur iPhone Duo elles sont souvent inégales.
Comment fonctionnent les size classes dans les panneaux d'ArrangementView ?
ArrangementView, nouveauté d'iOS 27.1, place une vue principale et une vue secondaire côte à côte, empilées ou superposées, selon l'espace et la posture. Le Tech Talk d'Apple Strike a pose with adaptive layouts on iPhone Duo décrit les critères qu'elle prend en compte pour une mise en page : la size class horizontale et verticale de la vue, le rapport d'aspect de la vue, et la présence éventuelle d'une région de division active, comme le pli.
En pratique, lisez les size classes à l'intérieur de chaque panneau plutôt que de supposer qu'un panneau hérite des valeurs de la fenêtre. Un panneau qui reçoit la moitié de l'écran intérieur dispose de bien moins de largeur que l'écran entier. @sarunw a publié un tableau des size classes que reçoit chaque vue sur iPhone Duo ; c'est une image, alors consultez la publication d'origine pour les valeurs par panneau plutôt que de vous fier à un résumé ici.
La réduction compte aussi. Un ingénieur DTS d'Apple a expliqué dans le fil 847800 qu'ArrangementView se réduit à l'affichage d'une seule vue quand sa division ne peut pas être respectée dans le rapport d'aspect, la posture ou la size class compact du moment. Elle conserve la vue dont la .layoutPriority est la plus élevée, ou la vue principale par défaut. Si votre panneau secondaire contient des commandes essentielles, offrez aux utilisateurs un autre moyen d'y accéder quand la largeur est compact.
struct EditorView: View {
var body: some View {
ArrangementView {
VideoPreview()
} secondary: {
EditingControls()
}
.arrangementViewStyle(.split)
}
}
struct VideoPreview: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
var body: some View {
PreviewCanvas()
.toolbar {
if horizontalSizeClass == .compact {
// Le panneau de commandes peut être masqué ; proposez-les depuis la barre d'outils.
ToolbarItem { EditingControlsButton() }
}
}
}
}
Les appels ArrangementView et .arrangementViewStyle(.split) sont présentés tels qu'Apple les montre dans le Tech Talk. La solution de repli en largeur compact suit l'approche suggérée dans le même fil du forum.
Comment tester les postures de l'iPhone Duo dans Xcode Device Hub ?
Vous n'avez pas besoin de l'appareil pour vérifier les size classes. Le Tech Talk d'Apple liste les étapes : choisissez le simulateur iPhone Duo dans Xcode 27.1, lancez votre app dans Device Hub et utilisez les boutons de commande en bas pour ouvrir, fermer, faire pivoter ou plier l'appareil. Device Hub et l'expérience plein écran nécessitent tous deux Xcode 27.1.
Passez en revue chaque ligne du tableau ci-dessus. Pour chaque posture, vérifiez que :
- La mise en page correspond aux size classes, et non à l'orientation.
- Le texte et les commandes restent dans la safe area de chaque côté, pas seulement en haut et en bas.
- Rien d'important ne chevauche le pli quand l'appareil est entrouvert.
- L'état survit à la transition : position de défilement, saisie de texte et sélection en cours.
Testez ensuite des largeurs plus étroites sur l'écran intérieur. Apple suggère de faire glisser l'app par l'indicateur d'accueil vers un côté de l'écran pour passer en multitâche Split View, puis vers l'autre côté. L'ingénieur DTS du forum a spécifiquement cité deux apps ouvertes sur l'écran intérieur comme configuration à vérifier, puisque votre app dispose alors de moins que la pleine largeur regular. @sarunw note aussi que le Device Hub de Xcode 27.2 peut simuler une pression mémoire, des animations au ralenti, une secousse et une chute, ce qui aide à traquer les bugs qui surviennent en pleine transition.
La posture entrouverte mérite une attention particulière dans les jeux. Une posture qui renvoie une largeur regular peut tout de même être physiquement coupée en deux, ce qu'exploitent des jeux comme Greens Mini Golf, avec le green sur la moitié inférieure et une caméra de caddie sur la moitié relevée. Les size classes ne vous disent pas où se trouve le pli ; c'est le rôle des reserved regions et des API de charnière.
Ce qu'il faut retenir
- Fermé, l'iPhone Duo renvoie des size classes d'iPhone : largeur compact et hauteur regular en portrait, compact dans les deux sens en paysage.
- Entrouvert ou ouvert, l'écran intérieur renvoie largeur regular et hauteur regular dans les deux orientations, comme un iPad.
- Ne faites pas dépendre votre code de l'orientation ni du modèle d'appareil. L'écran intérieur ignore les orientations prises en charge, et Apple recommande de s'adapter à l'espace disponible.
- Lisez
horizontalSizeClassetverticalSizeClassdepuis l'environnement SwiftUI outraitCollectionen UIKit, et préférez les conteneurs système qui s'adaptent déjà. - Dans ArrangementView, lisez les size classes par panneau et prévoyez que la division se réduise à une seule vue.
- Testez chaque posture et la Split View dans Device Hub avec Xcode 27.1.
Les size classes ne sont qu'une première étape. Découvrez ensuite comment les barres passent sur le côté de l'écran dans notre guide sur la barre d'outils verticale de l'iPhone Duo, parcourez la checklist complète pour préparer votre app à l'iPhone Duo, ou explorez les jeux qui exploitent déjà la charnière sur Built for the fold.
Questions fréquentes
Quelle size class utilise l'écran intérieur de l'iPhone Duo ?
L'écran intérieur renvoie une size class horizontale regular et une size class verticale regular, en portrait comme en paysage, que l'appareil soit entrouvert ou entièrement ouvert. C'est la même combinaison que celle d'une app iPad en plein écran.
Quelle size class utilise l'écran extérieur de l'iPhone Duo ?
L'écran extérieur se comporte comme les autres modèles d'iPhone. En portrait, il renvoie largeur compact et hauteur regular ; en paysage, largeur compact et hauteur compact.
Faut-il tester l'orientation ou le modèle d'appareil pour adapter mon app à l'iPhone Duo ?
Non. Apple recommande d'éviter la logique spécifique à un appareil et les tests d'orientation, et de s'adapter plutôt aux size classes et à l'espace disponible. L'écran intérieur ne respecte pas les orientations d'interface prises en charge par votre app, donc l'orientation n'y est pas un signal de mise en page fiable.
Existe-t-il un trait UITraitCollection pour le pli ou la posture de l'iPhone Duo ?
Un ingénieur Apple a indiqué sur les forums développeurs qu'il n'existe pas de traits de trait collection pour la posture. Utilisez les size classes pour la mise en page, les reserved regions pour le pli, et les API de charnière si vous avez besoin de l'état du pli lui-même.
Comment tester les size classes de l'iPhone Duo sans l'appareil ?
Lancez votre app dans le simulateur iPhone Duo de Device Hub, qui nécessite Xcode 27.1. Ses commandes permettent d'ouvrir, fermer, faire pivoter et plier l'appareil, et vous pouvez faire glisser l'app en Split View sur l'écran intérieur pour tester des largeurs plus étroites.
Sources
- Size classes on iPhone Duo: folded portrait, folded landscape, half-open and open · @sarunw on X
- Folded, iPhone Duo is an iPhone. Unfolded, it's an iPad. · @sarunw on X
- Start with size classes, layout margins and safe area insets · @sarunw on X
- Size classes of each view in ArrangementView on iPhone Duo · @sarunw on X
- Prepare your app for iPhone Duo · Apple Developer
- Strike a pose with adaptive layouts on iPhone Duo · Apple Developer
- Does the iPhone Duo inner display use a regular horizontal size class? · Apple Developer Forums
- Adapting an existing UIKit app for iPhone Duo at runtime · Apple Developer Forums
- Hinge articulation and UITraitCollection in custom view controllers · Apple Developer Forums
- How should ArrangementView behave across iPhone Duo display modes? · Apple Developer Forums
- iPhone Duo Apps, What Changes in Your Code and What to Do With Old Ones · Pasquale Pillitteri
Faites du pli une partie de votre app.
Nous présentons les apps et les jeux qui exploitent vraiment l’iPhone Duo. Envoyez-nous la vôtre avec un lien vers l’App Store, ou découvrez ce que d’autres ont créé.