Building against the iOS 27.1 SDK changes how bars are laid out on iPhone Duo: navigation, toolbar, and tab bar controls share a single vertical region at the side, preserving vertical space for content. Picture your existing bars rotated ninety degrees into a column.
Where it applies
| Display and orientation | Bar placement |
|---|---|
| Outer display (closed) | Side, on the right — the outer display is wider and shorter than other iPhones |
| Inner display, landscape | Side — kept there so controls stay where they were when closed |
| Inner display, portrait | Horizontal — there is enough height for standard bars |
Every pose except the inner display in portrait puts bars at the side, so this is not a landscape edge case: the closed device shows a vertical bar in both orientations. In Split View on the inner display, each app places its controls along its own outer edge. Items overflow most often on the outer display in landscape, and also when other interface competes for the space, such as the keyboard, or Picture in Picture on the open device in portrait.
What you get automatically
Your existing layout maps across directly. Toolbar buttons from the top of the screen move to the top of the column, buttons from the bottom move to the bottom, and a tab bar stays bottom-aligned. Items too wide for the column, such as a text button or a segmented control, stay in the navigation bar.
Standard containers participate without code changes. Use UINavigationController and UITabBarController, or their SwiftUI equivalents, and the system handles placement. Custom UIToolbar content is not considered for this treatment.
The bar stays on the same side in right-to-left languages, because it is aligned with the hardware rather than the reading direction. In a split view only the detail column participates, and inspectors do not get a bar of their own.
Controlling placement
Order matters in a vertical bar. The top is reserved for primary navigation such as Back or Close, followed directly by prominent actions such as Done. Your remaining items keep their original groups, with a vertical space separating what came from the top bar and what came from the bottom bar:
.toolbar {
// Primary navigation: first in the column
ToolbarItem(placement: .cancellationAction) { CloseButton() }
// Prominent action: directly after navigation
ToolbarItem(placement: .topBarPinnedTrailing) { DoneButton() }
}
// UIKit
navigationItem.leftItemsSupplementBackButton = false
navigationItem.leadingItemGroups = [UIBarButtonItemGroup(…)]
navigationItem.pinnedTrailingGroup = UIBarButtonItemGroup(…)
A navigation controller adds the Back button for you. Use a leading item only for a custom Back or Close button, and keep leftItemsSupplementBackButton at its default of false.
Items are not rotated. The system decides, item by item, whether each one belongs on the vertical axis or stays in a horizontal bar: items with a symbol move to the side, text-only items stay horizontal, and custom views stay horizontal by default. axisBehavior overrides that choice:
.axisBehavior(.verticalPreferred) // let a custom view join the vertical bar
.axisBehavior(.horizontalOnly) // keep an item in the horizontal bar
Use .horizontalOnly for an item that switches between a symbol and text, such as a Select button that becomes Done, so it does not jump between axes. The system Edit button already does this.
// UIKit
item.axisBehavior = .verticalPreferred
Adapting custom views
A custom view you opt into the vertical bar must fit the bar’s fixed width or have its own vertical layout. Vertical bars have a fixed width and flexible item height, the reverse of horizontal bars. To adapt, read the edge, which is set when items can sit on the vertical axis and is nil or unspecified when they cannot:
@Environment(\.toolbarVerticalEdge) private var edge
// UIKit
switch traitCollection.verticalBarEdge { … }
Apple’s content advice is to prefer symbol-only items and to minimise text-only items and custom views that show both text and a symbol. A count shown as text next to an inbox symbol, for example, can become a badge on a symbol-only item. Text that carries real information, such as a cart total, belongs in the horizontal bar.
A few defaults that catch custom views out:
- Flexible spacers have zero size on the vertical axis; fixed spacers keep their minimum size.
- A vertical bar has no scroll-edge effect, but it gains a background when Reduce Transparency is on, so keep custom content legible either way.
- Keyboard accessory bars stay attached to the keyboard.
- Sheets on the outer display show an existing toolbar vertically. On the inner display they are centred with horizontal items; a sheet you move to the right with
preferredPlacementgets a vertical bar, and one on the left does not.
Opting out
Not every screen benefits. Apple names single-page layouts with heavy bottom content, such as a calculator, and sheets with only a close button:
.toolbarVerticalBehavior(.disabled)
// UIKit
override var preferredVerticalBarBehavior: UIVerticalBarBehavior { .disabled }
Opt out deliberately, per screen — not globally to avoid doing the work.
How to verify
Audit every screen’s bar on the closed outer display first, then on the inner display in landscape, and confirm it returns to horizontal in portrait. Check that labels are readable, that custom views are not clipped, and that the items you consider essential are visible rather than buried in overflow.