Développeurs
Barre d'onglets de l'iPhone Duo : guide TabView et NavigationSplitView
La barre d'onglets de l'iPhone Duo passe dans la barre verticale : quelle colonne de NavigationSplitView en reçoit une, l'inspecteur qui reste horizontal et les marges.
Par la rédaction AppleDuoPublié le 9 min de lecture
Sur cette page
- La barre d'onglets passe-t-elle sur le côté sur iPhone Duo ?
- Quels éléments passent à la verticale, et lesquels restent horizontaux ?
- Comment choisir entre la barre d'onglets et la barre d'outils pour la compression ?
- Puis-je afficher une barre latérale au lieu d'une barre d'onglets sur l'écran intérieur ?
- Quelle colonne de NavigationSplitView reçoit une barre verticale sur iPhone Duo ?
- Pourquoi un inspecteur déployé garde-t-il des éléments horizontaux ?
- Quelle size class chaque colonne de NavigationSplitView renvoie-t-elle ?
- Comment disposer le contenu à côté de la barre verticale sans supposer de marges fixes ?
- À retenir
Lancez une app dotée d'un TabView ou d'un UITabBarController sur iPhone Duo : la barre d'onglets de l'iPhone Duo n'est plus une rangée au bas de l'écran. Elle passe sur le côté, dans la même barre verticale que vos éléments de navigation et de barre d'outils. Les split views changent aussi : dans un NavigationSplitView, une seule colonne reçoit cette barre verticale, et un inspecteur déployé n'en reçoit aucune.
Ce guide explique ce qui arrive aux barres d'onglets, aux colonnes de split view et aux inspecteurs, comment choisir la barre qui cède quand la place manque, et comment disposer le contenu à côté de barres qui ne sont plus symétriques. Pour les règles générales de la barre verticale, comme les symboles, le débordement ou la désactivation, consultez notre guide de la barre d'outils verticale de l'iPhone Duo. Tout ce qui suit provient du Tech Talk Raise the bar with iPhone Duo, de la documentation d'Apple, d'un résumé DTS sur les forums d'Apple et des publications de @sarunw. Ces API sont nouvelles dans iOS 27.0 et 27.1, et certains détails peuvent changer d'une version à l'autre.
La barre d'onglets passe-t-elle sur le côté sur iPhone Duo ?
Oui. Le Tech Talk d'Apple Prepare your app for iPhone Duo indique que TabView et UITabBarController s'adaptent à toutes les postures, et que les onglets apparaissent sur l'écran intérieur et l'écran extérieur, en se disposant « verticalement lorsque c'est pertinent ». Cela correspond aux mêmes contextes que les autres barres : l'écran extérieur, et l'écran intérieur en paysage. En portrait sur l'écran intérieur, les barres restent horizontales.
Apple décrit les commandes de navigation, de barre d'outils et de barre d'onglets partageant une même zone, et suggère d'imaginer la mise en page pivotée de 90 degrés en une pile verticale. Ses exemples montrent les trois combinaisons : Notes utilise une barre d'outils, Horloge une barre d'onglets, et Forme les deux. Comme le décrit @sarunw, la rangée horizontale d'onglets « devient une pile verticale près du bas de la barre ». Les éléments de la barre d'outils occupent le haut de la barre, là où les recommandations d'Apple placent Retour, Fermer et les actions importantes comme Terminé.
Vous obtenez ce comportement en compilant avec le SDK iOS 27.1 et en utilisant le conteneur système. Le résumé du group lab iPhone Duo rédigé par un ingénieur DTS d'Apple est explicite : l'adaptation est liée aux conteneurs, TabView et UITabBarController, pas aux barres autonomes. Une barre d'onglets personnalisée, ou une UITabBar que vous placez vous-même, ne bougera pas. Si vous devez en garder une, positionnez-la à l'aide de la valeur d'environnement toolbarVerticalEdge ou du trait verticalBarEdge, comme l'explique le guide de la barre d'outils verticale.
Quels éléments passent à la verticale, et lesquels restent horizontaux ?
Les onglets suivent les mêmes règles que le reste de la barre. Le Tech Talk d'Apple le formule ainsi : les éléments dotés d'une icône, comme les boutons Retour et Partager, passent sur l'axe vertical, tandis que les éléments uniquement textuels, comme le bouton Modifier, restent sur l'axe horizontal. Le résumé de @sarunw dit la même chose : les éléments à icône comme Retour et Partager passent dans la barre verticale, et les éléments textuels comme Modifier restent horizontaux.
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button("Share", systemImage: "square.and.arrow.up") { share() }
}
ToolbarItem(placement: .secondaryAction) {
Button("Edit") { isEditing.toggle() }
}
}
Dans cet exemple, Share a un symbole et peut passer à la verticale. Edit n'a qu'un titre : il reste horizontal. Si vous voulez Edit dans la barre verticale, donnez-lui aussi un symbole ; le résumé DTS précise que le système n'affiche pas verticalement un élément qui n'a qu'un titre. Gardez le titre sur chaque élément, car le système l'affiche dans les menus de débordement.
Pour les onglets, le même conseil vaut pour chaque Tab : donnez-lui un titre et un systemImage, comme dans Tab("Recents", systemImage: "clock"). Les badges permettent de conserver une information sans ajouter de texte. Le Tech Talk d'Apple transforme un élément texte et symbole en symbole seul avec .badge(7) en SwiftUI ou item.badge = .count(7) en UIKit.
Comment choisir entre la barre d'onglets et la barre d'outils pour la compression ?
Quand une barre d'onglets et une barre d'outils partagent la barre verticale, l'une des deux manque de place la première, surtout sur l'écran extérieur en paysage. Le Tech Talk d'Apple décrit deux comportements pour deux types d'apps. Dans une vue axée sur la navigation, comme Podcasts, la barre d'outils se compresse en premier pour que les destinations principales restent accessibles. C'est le comportement par défaut. Dans une vue axée sur les tâches, comme l'app Jeux, la barre d'onglets se compresse en premier pour garder visibles les actions fréquentes. La barre qui cède se replie dans un bouton de débordement.
toolbarVerticalCompressionBehavior(_:) de SwiftUI, nouveau dans iOS 27.1, définit la préférence vue par vue. En UIKit, définissez verticalBarCompressionBehavior sur le navigation item du view controller, également nouveau dans iOS 27.1.
TabView {
Tab("Recents", systemImage: "clock") {
NavigationStack {
RecentsView()
.toolbar {
Button("Up", systemImage: "chevron.up") { moveUp() }
Button("Down", systemImage: "chevron.down") { moveDown() }
}
.toolbarVerticalCompressionBehavior(.prefersToolbarItems)
}
}
}
navigationItem.verticalBarCompressionBehavior = .prefersBarItems
Le premier exemple suit la documentation d'Apple, qui prend une app de productivité comme Fichiers pour illustrer la préférence pour les éléments de la barre d'outils. Le second est la forme UIKit présentée dans le Tech Talk. Les valeurs diffèrent légèrement d'un framework à l'autre :
| Préférence | SwiftUI | UIKit |
|---|---|---|
| Laisser le système décider (par défaut) | .automatic | .automatic |
| Garder visibles les éléments de la barre d'outils | .prefersToolbarItems | .prefersBarItems |
| Garder visible la barre d'onglets | .prefersTabBar | .prefersTabBar |
Au sein de la barre d'outils, la priorité compte toujours. Comme le note @sarunw, appliquez .visibilityPriority(.high) aux éléments importants pour qu'ils restent visibles quand la place est limitée. Le guide de la barre d'outils verticale détaille l'ordre et le débordement.
Puis-je afficher une barre latérale au lieu d'une barre d'onglets sur l'écran intérieur ?
Oui. Sur iPhone, iOS affiche une barre d'onglets au lieu de s'adapter en barre latérale comme le fait iPadOS. Sur l'écran intérieur de l'iPhone Duo, Apple vous permet d'opter pour une barre latérale afin d'offrir une navigation plus riche. En SwiftUI, utilisez defaultTabBarPlacement(_:) avec le style sidebarAdaptable. En UIKit, définissez la propriété preferredPlacement de la sidebar. Les deux sont disponibles à partir d'iOS 27.0.
TabView {
Tab("Home", systemImage: "house") { HomeView() }
Tab("Favorites", systemImage: "star") { FavoritesView() }
}
.tabViewStyle(.sidebarAdaptable)
.defaultTabBarPlacement(.sidebar)
tabBarController.sidebar.preferredPlacement = .sidebar
La documentation d'Apple indique que defaultTabBarPlacement(_:) s'applique là où le style se résout en barre latérale ou en barre d'onglets, comme sur iPhone, et n'a aucun effet sur iPadOS, où la barre peut se transformer. En UIKit, le placement automatique se résout en barre d'onglets sur iOS.
Un dernier détail sur TabView : si vous désactivez la barre verticale avec toolbarVerticalBehavior(.disabled), la documentation d'Apple précise qu'un TabView résout le comportement à partir de l'onglet sélectionné. Gardez le même choix pour tous les onglets afin que la mise en page ne saute pas quand l'utilisateur change d'onglet.
Quelle colonne de NavigationSplitView reçoit une barre verticale sur iPhone Duo ?
Seulement la colonne de détail. La règle d'Apple veut que les éléments de la barre d'outils ne passent à la verticale que si leur conteneur longe le bord de l'écran : dans une split view, seule la colonne de détail est concernée, et les éléments des autres colonnes restent horizontaux. @sarunw le résume ainsi : une barre ne passe à la verticale que si son conteneur longe le bord de l'écran.
Le résumé DTS détaille le cas de l'écran intérieur : le système affiche les barres horizontalement pour la colonne de barre latérale ou de contenu, et verticalement sur le bord trailing pour la colonne de détail. Lorsque l'iPhone Duo est fermé, NavigationSplitView et UISplitViewController se réduisent à une navigation en pile unique ; lorsqu'il est ouvert, ils juxtaposent ou superposent leurs colonnes.
| Contexte | Colonnes de barre latérale et de contenu | Colonne de détail | Inspecteur déployé |
|---|---|---|---|
| Écran intérieur, paysage | Barres horizontales | Barre verticale, bord trailing | Éléments horizontaux |
| Écran intérieur, portrait | Barres horizontales | Barres horizontales | Éléments horizontaux |
| Écran extérieur (fermé) | Réduites en une seule pile | Réduite en une seule pile | Présenté en sheet |
La ligne de l'écran extérieur reflète le comportement de réduction décrit par Apple et la documentation de l'inspecteur ; la pile suit ensuite les règles de barre verticale de l'écran extérieur. Comme la colonne la plus en position trailing détermine aussi toolbarVerticalBehavior pour une split view, placez toute désactivation sur la vue de la colonne de détail.
NavigationSplitView {
SidebarList(selection: $selection)
} detail: {
DetailView(item: selection)
.toolbar {
Button("Share", systemImage: "square.and.arrow.up") { share() }
}
.inspector(isPresented: $showsInspector) {
InspectorView(item: selection)
}
}
Ici, le bouton Share se trouve dans la colonne de détail : c'est donc l'élément qui peut passer à la verticale. Les éléments de barre d'outils que vous attachez à la liste de la barre latérale restent horizontaux.
Pourquoi un inspecteur déployé garde-t-il des éléments horizontaux ?
Le Tech Talk d'Apple explique que les colonnes de détail ayant déjà une barre verticale, les inspecteurs n'en reçoivent pas une propre lorsqu'ils sont déployés, pour éviter toute confusion. Selon @sarunw, la colonne de détail a déjà une barre verticale, et « une seconde entrerait en concurrence avec elle ».
Le résumé DTS explique comment l'ensemble s'articule. Sur l'écran intérieur, une barre latérale et un inspecteur peuvent coexister si vous utilisez NavigationSplitView et appliquez inspector(isPresented:content:) à la vue de détail. L'inspecteur se coordonne avec la mise en page trailing de la colonne de détail au lieu d'ajouter une barre. La documentation d'Apple sur l'inspecteur précise aussi qu'il s'affiche comme une colonne trailing dans une size class horizontale regular et devient une sheet dans une size class compact ; les réponses DTS indiquent que sur l'écran extérieur, ou quand la split view est réduite, il apparaît en sheet.
En pratique, concevez les commandes de l'inspecteur pour une barre horizontale, avec des titres là où ils aident. Ne comptez pas sur la barre verticale pour des actions qui n'existent que dans l'inspecteur.
Quelle size class chaque colonne de NavigationSplitView renvoie-t-elle ?
Les size classes de la fenêtre sur iPhone Duo sont bien documentées : largeur compact sur l'écran extérieur, largeur et hauteur regular sur l'écran intérieur, quelle que soit l'orientation. Notre guide des size classes de l'iPhone Duo donne le tableau complet. Les colonnes sont une autre question. @sarunw a publié un tableau des size classes de chaque colonne d'un NavigationSplitView sur iPhone Duo, et ce qu'il faut en retenir, c'est qu'une colonne ne renvoie pas forcément les valeurs de la fenêtre.
Lisez donc les size classes dans la colonne qui gère la mise en page, et non au niveau de la fenêtre ou de la racine :
struct DetailView: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
let item: Item?
var body: some View {
if horizontalSizeClass == .regular {
WideDetailLayout(item: item)
} else {
CompactDetailLayout(item: item)
}
}
}
Comme la valeur d'environnement est lue dans DetailView, elle reflète les traits propres à la colonne. Le Tech Talk Strike a pose d'Apple ajoute un détail lié à l'écran intérieur : dans une app en split view comme Rappels, le système garde les deux colonnes visibles en ajustant leur largeur pour obtenir un partage égal 50/50. Si vous construisez vous-même des panneaux plutôt que des colonnes, ArrangementView donne à chaque panneau ses propres size classes de façon similaire.
Comment disposer le contenu à côté de la barre verticale sans supposer de marges fixes ?
Quand la colonne de détail a une barre verticale d'un côté et la barre latérale de l'autre, ses marges ne sont pas identiques sur les deux bords. Le conseil de @sarunw est bref : ne supposez pas de marges fixes, car elles ne sont pas forcément symétriques selon l'appareil et l'orientation ; utilisez layoutMarginsGuide. Le Tech Talk d'Apple indique que les marges de mise en page sur iPhone Duo sont asymétriques comme les safe areas : le contenu de premier plan peut se rapprocher des boutons verticaux tandis que la marge opposée est préservée.
NSLayoutConstraint.activate([
headerView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
headerView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
headerView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor)
])
S'ancrer à layoutMarginsGuide récupère la marge de chaque bord séparément, sans valeur codée en dur de 16 ou 20 points. Les barres se placent aussi en dehors de la safe area, et Apple note que les barres verticales fournissent des marges intérieures leading et trailing plutôt qu'en haut et en bas. Pour l'équivalent SwiftUI et l'ensemble des règles de marges, consultez safe areas et marges de contenu de l'iPhone Duo.
À retenir
- Utilisez
TabViewouUITabBarController. Leurs onglets passent dans la barre verticale sous forme de pile près du bas ; les barres d'onglets personnalisées ne bougent pas. - Donnez à chaque onglet et à chaque élément de barre d'outils un symbole et un titre. Les éléments à icône passent à la verticale, les éléments textuels restent horizontaux.
- Choisissez la barre qui se compresse en premier avec
toolbarVerticalCompressionBehaviorouverticalBarCompressionBehavior. Par défaut, c'est la barre d'outils. - Dans un
NavigationSplitView, seule la colonne de détail reçoit une barre verticale, et un inspecteur déployé garde ses éléments horizontaux. - Lisez les size classes dans chaque colonne, et ancrez le contenu à
layoutMarginsGuideau lieu de supposer des marges égales.
Ensuite, parcourez le reste des règles de la barre verticale dans notre guide de la barre d'outils verticale, puis découvrez comment d'autres apps et jeux exploitent l'appareil sur Built for the fold.
Questions fréquentes
La barre d'onglets se déplace-t-elle sur iPhone Duo ?
Oui. Les apps compilées avec le SDK iOS 27.1 qui utilisent TabView ou UITabBarController voient leurs onglets se disposer verticalement lorsque c'est pertinent, en partageant la barre verticale avec les éléments de navigation et de barre d'outils. Les barres d'onglets personnalisées et les instances autonomes de UITabBar ne bougent pas.
Quelle colonne de NavigationSplitView reçoit une barre verticale sur iPhone Duo ?
Seulement la colonne de détail, car c'est elle qui longe le bord de l'écran. Sur l'écran intérieur, les colonnes de barre latérale et de contenu gardent des barres horizontales, et la barre de la colonne de détail passe à la verticale sur le bord trailing.
Pourquoi un inspecteur garde-t-il des éléments horizontaux sur iPhone Duo ?
La colonne de détail a déjà une barre verticale, et une seconde à côté entrerait en concurrence avec elle. Apple a choisi de ne pas donner de barre verticale propre aux inspecteurs déployés : leurs éléments restent donc horizontaux.
Comment garder les onglets visibles quand la barre verticale manque de place ?
Appliquez toolbarVerticalCompressionBehavior(.prefersTabBar) en SwiftUI, ou définissez verticalBarCompressionBehavior sur .prefersTabBar dans le navigation item en UIKit. Par défaut, c'est la barre d'outils qui se compresse en premier pour que les destinations principales restent accessibles.
Puis-je afficher une barre latérale au lieu d'une barre d'onglets sur l'écran intérieur de l'iPhone Duo ?
Oui. En SwiftUI, utilisez le style de tab view sidebarAdaptable avec defaultTabBarPlacement(.sidebar). En UIKit, définissez la propriété preferredPlacement de la sidebar du tab bar controller sur .sidebar. Les deux sont disponibles à partir d'iOS 27.0.
Sources
- Raise the bar with iPhone Duo · Apple Developer
- Prepare your app for iPhone Duo · Apple Developer
- Strike a pose with adaptive layouts on iPhone Duo · Apple Developer
- toolbarVerticalCompressionBehavior(_:) · Apple Developer Documentation
- verticalBarCompressionBehavior · Apple Developer Documentation
- toolbarVerticalBehavior(_:) · Apple Developer Documentation
- defaultTabBarPlacement(_:) · Apple Developer Documentation
- UITabBarController.Sidebar preferredPlacement · Apple Developer Documentation
- inspector(isPresented:content:) · Apple Developer Documentation
- layoutMarginsGuide · Apple Developer Documentation
- A Summary of the iPhone Duo Group Lab · Apple Developer Forums
- Tab bars move to the side on iPhone Duo too · @sarunw on X
- Items with an icon move to the vertical bar; text-only items stay horizontal · @sarunw on X
- A bar only goes vertical when its container sits along the display edge · @sarunw on X
- An expanded inspector keeps its items horizontal · @sarunw on X
- Size classes of each column in NavigationSplitView on iPhone Duo · @sarunw on X
- Set .visibilityPriority(.high) for important items · @sarunw on X
- Don't assume padding; use layoutMarginsGuide · @sarunw on X
- What can the APIs added in iOS 27.1 for iPhone Duo do? · DevelopersIO (Classmethod)
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éé.