The most visible change when you link against the iOS 27.1 SDK is that your bars move. On the outer display, and on the inner display in landscape, navigation bar items, toolbar items and tab bar items rotate into a single vertical bar along the side, under the status bar. That keeps vertical space for content and puts controls where a thumb can reach them. In portrait on the inner display, bars go back to the top and bottom.12
The vertical bar stays on the same side of the hardware in right-to-left languages; your content mirrors around it.1
Only container-managed bars move
The system only rearranges bars it owns:
- SwiftUI: the
toolbarmodifier inside aNavigationStackorNavigationSplitView, andTabView. - UIKit:
UINavigationControllerandUITabBarController. SettoolbarItemson a view controller inside a navigation controller.
Content in a UIToolbar, UINavigationBar or UITabBar you created yourself is not considered, and neither is a standalone SwiftUI toolbar outside a navigation container. If you built your tab bar from scratch (Lottie animations are a common reason), it will stay horizontal and may collide with the status bar.3 Either migrate to the container’s bar, or keep it and lay it out yourself using toolbarVerticalEdge / verticalBarEdge and reserved regions.
// SwiftUI: items in a navigation container's toolbar can go vertical
NavigationStack {
ContentView()
.toolbar {
ToolbarItem(placement: .bottomBar) { /* ... */ }
}
}
Some containers have rules of their own:
- In a split view, only the detail column gets a vertical bar.
- An expanded inspector doesn’t get its own bar.
- On the inner display, sheets are centered and keep horizontal bars. A sheet placed on the trailing side gets a vertical bar; one placed on the leading side doesn’t.
- Keyboard accessory bars stay horizontal.1
Order: what goes at the top
A vertical bar reads top to bottom:
- Primary navigation: back or close.
- Prominent actions, such as Done.
- Everything else, in its original groups, with a spacer between top and bottom placements.1
A navigation controller adds the back button for you. For a custom back or close button, use the cancellationAction placement in SwiftUI; in UIKit, a leading item group with leftItemsSupplementBackButton = false. Pin prominent actions with topBarPinnedTrailing or pinnedTrailingGroup:
// SwiftUI
.toolbar {
ToolbarItem(placement: .topBarPinnedTrailing) { /* Done */ }
}
// UIKit
navigationItem.pinnedTrailingGroup = UIBarButtonItemGroup(/* ... */)
Give every item a symbol and a title
A vertical bar has a fixed item width, so it suits symbol-only items. The system picks what to show:
- Items with an icon, like back or share, go vertical.
- Text-only items, like Edit, stay horizontal.
- Overflow menus show the title and the icon.
So always provide both. If you use Label in SwiftUI, or set both title and image on UIBarButtonItem, you’re mostly done. The same applies to tab items: a title-only tab item won’t be shown vertically.1
Where you show text next to a symbol, ask whether the text carries information of its own. An inbox count can become a badge on a symbol-only item:
// SwiftUI
InboxButton().badge(7)
// UIKit
item.badge = .count(7)
Text that matters on its own, like a cart total, should stay in a horizontal bar.1
Control the axis of custom items
Custom views stay horizontal by default. Use axisBehavior to change that:
| Behavior | Use for |
|---|---|
| Default | Let the system decide from the content |
.verticalPreferred |
Custom views that work vertically, like a profile picture or compass |
.horizontalOnly |
Items that switch between symbol and text, like a Select/Done button |
// SwiftUI
ToolbarItem { ProfileView() }
.axisBehavior(.verticalPreferred)
// UIKit
let item = UIBarButtonItem(customView: ProfileView())
item.axisBehavior = .verticalPreferred
When a custom view can go vertical, it has to fit the bar’s fixed width or switch to a vertical layout. Read where it is with @Environment(\.toolbarVerticalEdge) in SwiftUI or traitCollection.verticalBarEdge in UIKit. The value is empty when the item can’t be vertical. Apple’s engineers call this the best signal for vertical-bar presentation, better than size class or orientation.3
Vertical bars have no scroll-edge effect and only get a background when Reduce Transparency is on, so keep custom content legible over anything. Flexible spacers collapse to zero on the vertical axis; don’t add your own padding.1
Plan for overflow
Vertical space runs out most often on the outer display in landscape, and when the keyboard or Picture in Picture appears. By default the toolbar compresses first, which keeps primary destinations in the tab bar.1 For task-focused screens where actions matter more, flip it:
// SwiftUI
.toolbarVerticalCompressionBehavior(.prefersToolbarItems)
// UIKit
navigationItem.verticalBarCompressionBehavior = .prefersBarItems
Items overflow from the bottom up. Mark the ones that should survive longest, such as Compose or anything with a badge:
// SwiftUI
ToolbarItem { /* ... */ }.visibilityPriority(.high)
// UIKit
item.visibilityPriority = .high
If you had your own “more” menu, fold it into the system one with ToolbarOverflowMenu (SwiftUI) or additionalOverflowItems (UIKit). The ellipsis symbol is reserved for that system menu.1
When to opt out
Most screens benefit. Apple suggests keeping horizontal bars for single-page, bottom-heavy layouts like a calculator, and for sheets with a single control:
// SwiftUI
NavigationStack { ContentView().toolbarVerticalBehavior(.disabled) }
// UIKit
override var preferredVerticalBarBehavior: UIVerticalBarBehavior { .disabled }
Checklist
- Build with the iOS 27.1 SDK.
- Move every bar onto a navigation or tab container.
- Give every item a symbol and a title; set
axisBehavioron custom views. - Set overflow compression and visibility priority on busy screens.