HELP YOUR AGENT UPDATE YOUR APP
iPhone
Duo Kit
Help your coding agent update your SwiftUI or UIKit app for iPhone Duo. Give it a practical workflow to inspect your app, adapt the interface, and check the result.
READY FOR YOUR AGENT
Get the skill.
A workflow for adapting your existing app.
SwiftUI and UIKit. Download as SKILL.md.
Read the complete skill
---
name: iphone-duo-kit
description: Inspect and update existing SwiftUI or UIKit apps to adapt their layouts, navigation, controls, and relevant interactions for iPhone Duo. Use when asked to optimize an app for iPhone Duo, implement support, or review readiness, using the supplied Apple material and exact API examples without inventing missing declarations.
---
# iPhone Duo Kit
Version: 1.1
Updated: 2026-09-11
### Changes in v1.1
Add the supplied Designing for iPhone Duo HIG as source block 5, strengthen continuity, camera-region, toolbar, and game guidance, and expand validation. Preserve all four original source blocks and all 41 Swift code examples unchanged. Keep the unresolved game-orientation scope explicit.
Help a coding agent understand how to update an existing SwiftUI or UIKit app for iPhone Duo. Work in the app's repository when implementation is requested: inspect the current UI, identify the changes it needs, implement the supported changes, and validate them with the available tools. If the user requests only an audit or explanation, stay within that scope.
Preserve the app's purpose, visual identity, data, and existing behavior while adapting it to the device's available space and supported interactions. Use the supplied material below for platform-specific guidance; do not invent iPhone Duo APIs or hardware behavior.
## App update workflow
1. **Inspect the existing app.** Read repository instructions and identify its SwiftUI and/or UIKit screens, navigation and content containers, custom controls, scene configuration, deployment targets, and available Xcode/SDK versions. Trace the app's actual layouts before choosing changes. Do not assume the same approach fits every screen.
2. **Audit layout assumptions.** Use source block 1 to locate references to the main screen, layout decisions based on device idiom or orientation, fixed-size layouts that cannot resize, and assumptions that opposite safe-area insets match. Identify the affected screens and relate each proposed change to the supplied guidance. Do not remove intentional constraints that still work across available sizes.
3. **Implement the adaptive foundation.** Apply the source's size-class, scene geometry, dynamic screen access, display-scale, safe-area, and corner guidance where relevant. Use standard navigation containers for their adaptive behavior. Preserve interactive foreground content inside the safe area and extend appropriate backgrounds independently. Configure sidebar navigation only where it suits the app. Apply source block 5 to preserve functionality, element state, and information hierarchy across displays; reveal additional hierarchy where useful without reinventing the app for each pose.
4. **Adapt content around reserved regions.** Read source blocks 2 and 5 before modifying centered controls, custom bars, or paired views. Choose displacement, split, or overlay behavior according to the existing views' relationship and the supplied rules. Keep continuously scrolling content flowing. Respect the restrictions on nesting navigation, arrangement, and scrolling containers. Use the exact reserved-region and arrangement examples; do not substitute hinge angles for layout APIs. Account for changing camera and Dynamic Island regions as described in source block 5; use reported geometry instead of hardcoded cutouts. Prefer only the movement needed to preserve visibility and access.
5. **Adapt navigation and toolbars.** Apply source blocks 4 and 5 to the app's existing system containers and toolbar items. Retain meaningful titles, keep related items on the appropriate axis, adapt custom views only when they support the vertical bar's constraints, and prioritize frequently used or status-bearing actions for overflow. Follow system placement, including the outer display, inner landscape versus portrait, and either outer edge in Split View multitasking; do not assume the vertical bar is always on the right. Keep pane-specific controls near the content they affect, and use system toolbar groups instead of manual fixed spacing. Apply an opt-out only when the source's guidance fits that screen.
6. **Handle relevant device capabilities.** Use source block 3 for resizing during multitasking, multiple-scene requests, and scene-accessory availability. Add hinge effects or camera capture accessories only when they support a requested or existing app feature. Respect the stated conditions, reset hinge-driven state when appropriate, and handle scene activation errors. Do not add a camera, player, guitar, or other sample feature merely because an example includes one. For an existing or requested game, apply source block 5 to preserve playability and consistent text/control sizes as the available aspect ratio changes. Prefer aspect-ratio adaptation over letterboxing or pillarboxing; if unavoidable, use appropriate artwork in the padding. Read the orientation caveat below before changing orientation configuration.
7. **Integrate with the real app.** Adapt app-specific view names, models, and business logic to the existing code while preserving the supplied platform API spellings and call patterns. Treat incremental and placeholder examples as reference fragments. Identify any exact declaration needed to finish implementation; do not fill gaps with plausible-looking APIs. If the installed SDK cannot validate a supplied API, explain that limitation and continue the changes that can be grounded and checked.
8. **Validate and deliver the changes.** Use Xcode 27.1 and DeviceHub, when available, to check opening, closing, rotating, and folding, and test asymmetric safe areas and Split View as directed by the source. Check that the app's existing workflows remain usable through resizing, using the HIG validation checklist below where relevant and supported by the available tools. Use relevant existing build and test commands; report the checks actually performed, remaining SDK/device limitations, and the files or changes delivered. Do not claim an app is verified or fully optimized without the corresponding evidence.
## Instructions for LLMs
The purpose, workflow, interpretation notes, validation checklist, version history, and navigation above the source blocks are an added skill wrapper. Source blocks 1–4 preserve the original supplied announcement material and code examples. Source block 5 preserves the subsequently supplied HIG text, including captions and display labels, with paragraph spacing and heading markers added for readability. Treat each block according to its stated provenance; the supplied text does not by itself establish independent verification of a live page or an SDK declaration.
- Use the supplied material as the source for iPhone Duo guidance. Do not replace unfamiliar APIs or behavior with assumptions from training data.
- Preserve every supplied API name, spelling, capitalization, argument label, signature, modifier, value, and example. Do not silently correct or reconcile differences between prose and code; retain both and identify any discrepancy that affects the requested implementation.
- Treat details absent from the material as unknown. Do not invent declarations, availability annotations, enum cases, thresholds, device dimensions, return types, or behavior. If an implementation requires a missing detail, request the exact declaration or additional authoritative material and continue only the work grounded in the available information.
- Keep all incremental examples, before/after examples, comments, placeholders, and ellipses. Interpret their supplied labels and context; do not treat an explicitly discouraged or “Before” example as adoption guidance. Do not represent incomplete snippets as complete, compilable programs. The retained “Copy Code” labels are source text outside the code fences.
- Read the guidance and code for each relevant source block before applying it. Use the original timestamps for source blocks 1–4 and the HIG section headings for source block 5 to trace decisions to their supporting material. Apply features according to the stated conditions and the app's needs.
- Use the validation guidance supplied in the source material when the required tools are available. Report which checks actually ran and what remains unverified; do not claim simulator or SDK validation without performing it.
- When maintaining this skill, preserve all supplied source content. Add new material or clarification separately unless the user explicitly requests an edit to the original text.
## Source interpretation notes
- **Game orientation is unresolved across the supplied sources.** Source block 1, 2:46, says the inner display does not honor supported interface orientations. Source block 5, Best practices, says games can lock to portrait or landscape. Preserve both statements. Do not infer a game-specific exception, an orientation-lock API, or guaranteed lock behavior from them. Check the applicable Apple game documentation and installed SDK declarations, and validate on the target device/simulator before relying on orientation locking. Continue supported adaptive-layout work while reporting this limitation.
- **Bar placement follows the system.** Source block 5 explicitly distinguishes the outer display, inner landscape, and inner portrait, and puts each multitasking app's controls on its outer edge. Read actual bar-edge, safe-area, and layout information using the supplied APIs; do not encode a fixed right edge or infer a unique layout from a device pose.
- **Design descriptions are not API declarations.** The HIG names concepts and types but supplies no new code examples. Keep the exact existing examples. Retrieve an exact declaration when implementation needs an unspecified operation, such as programmatically collapsing an overlay's secondary view; do not derive a plausible API from prose.
## HIG validation checklist
Use these checks for the app's relevant screens and capabilities when supported by available tools. Report unperformed checks as unverified; do not add features solely to exercise the checklist. The concrete state examples below are editorial test suggestions derived from the HIG's continuity guidance.
| Scenario | Check |
| --- | --- |
| Open, close, fold, and resize | Preserve the active task and relevant element state, such as selection, navigation location, and an in-progress draft. Keep the same content and actions accessible, including through overflow. |
| Outer display; inner landscape and portrait | Let standard containers adapt their bars; keep controls recognizable and avoid excessive movement or hardcoded placement. |
| Split View multitasking in both app positions | Verify the app with controls on either outer edge, asymmetric safe areas, and changing window widths. Keep pane-specific actions with their pane. |
| Inner camera inactive, active, then inactive | Verify that foreground controls remain visible and usable as the camera's reserved region appears and disappears, where camera-state testing is available. |
| Outer camera and expanded Live Activities | Check the persistent camera region and Dynamic Island expansion without hardcoding their geometry, where the system state can be exercised. |
| Paired views, grids, and scrolling content | Check minimal displacement, suitable even-column grids, arrangement nesting, and uninterrupted scrolling; preserve the existing view relationships. |
| Toolbar compression and overflow | Preserve navigation destinations or task actions according to the screen's purpose, keep important status visible, and use system grouping and overflow. |
| Games, when applicable | Check playability, screen coverage, and consistent text/control sizes across poses and aspect ratios. Treat orientation-lock behavior as unverified until the source discrepancy is resolved for the target. |
## Source navigation
The topic labels below are editorial navigation, not supplied session titles. Source blocks 1–4 contain timestamped guidance followed by their timestamped code examples. Source block 5 contains the supplied Human Interface Guidelines text in its original order.
| Source block | Topics |
| --- | --- |
| [Source block 1](#source-block-1) | SDK and Xcode, resizing, size classes, screens, navigation, safe areas, reserved regions |
| [Source block 2](#source-block-2) | Hinge-aware layouts, displacement, reserved region queries, split and overlay arrangements |
| [Source block 3](#source-block-3) | Hinge interactions, multitasking, multiple scenes, camera capture accessories |
| [Source block 4](#source-block-4) | Vertical bars, item ordering, axis behavior, custom views, overflow and visibility priorities |
| [Source block 5](#source-block-5) | Human Interface Guidelines: continuity, anatomy, poses, dynamic layouts, camera regions, vertical controls, and games |
## Source block 1
### Timestamped guidance
#### 00 - Introduction
David Jackson from the UI Frameworks team outlines how to bring your app to iPhone Duo: getting started in Xcode, general resizing guidance, and layout guidance specific to iPhone Duo.
#### 0:30 - Build with the latest SDK
Your app runs on iPhone Duo even without recompiling, but screen usage improves with each SDK. The iOS 27 SDK extends your app left of the status bar on the inner display; the iOS 27.1 SDK reaches the screen edge and lays standard navigation and toolbar buttons out vertically.
#### 1:17 - Get started in Xcode
Download Xcode 27.1 and run your app in the iPhone Duo simulator using DeviceHub. On-screen control buttons let you open, close, rotate, and fold the device to check your layout in every pose.
#### 1:33 - Adopt flexible layouts
iPhone Duo extends the long-standing need for adaptive layout — new screen shapes, camera locations, and iPhone mirroring on the Mac. Avoid assumptions about display size or capability based on user interface idiom, and design across a continuum of sizes.
#### 2:46 - Use size classes
Size classes express the experience your app should provide for the available space — the environment in SwiftUI, trait collection in UIKit. The outer display behaves like other iPhone models, while the inner display is regular in both dimensions, leaving room for sidebars. The inner display doesn't honor supported interface orientations, so use size classes rather than orientation for layout decisions.
#### 3:57 - Avoid screen assumptions
Don't reference the main screen on a two-display device — it's ambiguous and will be deprecated. Prefer the environment, trait collection, or the scene's bounds, and access screens dynamically from the window scene. Use the iOS 26 Concentricity APIs, ConcentricRectangle and UICornerConfiguration, to fit the screen's corners.
#### 5:01 - Adopt standard navigation
NavigationSplitView, UISplitViewController, TabView, and UITabBarController are fully adaptive across every pose — columns collapse when closed and tile or overlay when open. On the inner display you can opt into a sidebar placement for richer navigation. Sheets, popovers, context menus, and alerts adapt as well.
#### 6:06 - Respect safe areas
Standard bars lay out outside the safe area and automatically avoid the status bar and camera. Keep interactive foreground content inside the safe area, and let background artwork extend past it with ignoresSafeArea or the view's bounds. Safe areas and layout margins are often asymmetric on iPhone Duo, so handle each side independently and test in Split View.
#### 8:08 - Use reserved regions
New in iOS 27.1, ReservedRegion in SwiftUI and UIViewReservedRegion in UIKit let custom UI claim as much screen space as possible without colliding with system UI — useful for custom bars and edge-to-edge designs.
#### 9:12 - Next steps
The app modernization skill introduced in "Modernize your UIKit app" is now called App Resizability in Xcode 27.1, with support for SwiftUI and iPhone Duo. Download Xcode 27.1, simulate with DeviceHub, follow the adaptive layout practices, and try the skill.
### Code examples
#### 2:59 - Read size classes
```swift
// SwiftUI
@Environment(\.horizontalSizeClass)
private var horizontalSizeClass
@Environment(\.verticalSizeClass)
private var verticalSizeClass
// UIKit
traitCollection.horizontalSizeClass
traitCollection.verticalSizeClass
```
Copy Code
#### 4:16 - Access the screen from the window scene
```swift
// Avoid referencing the main screen on a two-display device.
// Access the screen dynamically from the window scene instead.
let screen = window?.windowScene?.screen
```
Copy Code
#### 4:30 - Match the screen corners with Concentricity
```swift
// SwiftUI
ConcentricRectangle()
.fill(Color.green)
.padding(8.0)
.ignoresSafeArea()
// UIKit
// UICornerConfiguration
```
Copy Code
#### 5:44 - Show a sidebar on the inner display
```swift
// SwiftUI
TabView { … }
.defaultTabBarPlacement(.sidebar)
// UIKit
tabBarController.sidebar.preferredPlacement = .sidebar
```
Copy Code
#### 6:52 - Align foreground content to the safe area
```swift
// UIKit
foreground.frame = view.bounds.inset(by: view.safeAreaInsets)
```
Copy Code
#### 7:07 - Let background content extend past the safe area
```swift
// SwiftUI
.ignoresSafeArea()
// UIKit
backgroundView.frame = view.bounds
```
Copy Code
#### 7:30 - Handle asymmetric safe area insets
```swift
// Avoid assuming insets on opposite sides are equal
let width = view.bounds.width - view.safeAreaInsets.left * 2
// Handle each side independently
let width = view.bounds.inset(by: view.safeAreaInsets).width
```
Copy Code
#### 9:25 - Replace main screen references
```swift
func updateThumbnail(from image: UIImage) {
// Before
let screenScale = UIScreen.main.scale
// After
let screenScale = traitCollection.displayScale
// ...
}
```
## Source block 2
### Timestamped guidance
#### 0:00 - Introduction
Maria, a Human Interface Designer on Apple's design system, and Harry, a UI Frameworks engineer, introduce how to create layouts that adapt to the unique characteristics of iPhone Duo.
#### 0:27 - Reserved regions on iPhone Duo
iPhone Duo has multiple displays, each with its own size class, plus hardware features that shape the available space — the hinge and the cameras on the outer and inner displays. These are called reserved regions, and you treat them like any other area your layout adapts to, such as window controls on iPadOS.
#### 1:29 - Designing around the hinge
When the device is partially folded like a book, the hinge divides the inner display into multiple usable regions as the display curves through the center. Just as a photo spread across a book's spine stops reading as one continuous image, content and controls that span the fold become harder to see.
#### 2:26 - Displacement patterns
Many interfaces flow naturally around reserved regions, while others benefit from displacement — adjusting the frame of existing elements based on available space. Displacement can scope from a single button to an entire container. Move elements independently when they can adapt alone, together when they work as a unit, and avoid excessive movement that weakens visual relationships. Continuously scrolling content like articles and feeds shouldn't displace.
#### 4:00 - Choose where content moves
Let purpose guide where content moves, and note that the right destination changes with how the device is used. Partially folded like a book, alerts move to the trailing side, closer to where they'll appear as the device closes. Propped on a table, the top region suits content viewed at a distance while the bottom suits interactive controls. When multiple regions work, keep things contextual.
#### 5:12 - Adapt content to its new region
Position and size change most often, but other visual properties adapt too. The system automatically repositions action sheets, alerts, menus, and popovers around reserved regions to keep them fully visible. In a split view like Reminders it keeps both columns visible with an even split, and a grid can preserve outer margins while increasing spacing around the hinge. Throughout, you're moving, resizing, or reorganizing what's already there.
#### 6:39 - Query reserved regions
In SwiftUI, query reserved regions with the new reservedRegion method on a GeometryProxy from GeometryReader or the onGeometryChange modifier. In UIKit, use the reservedRegion method on UIView. Query a region's frame to incorporate it into your layout. The fold is backed by a division region, because it divides a larger area into smaller ones.
#### 7:50 - Division and occlusion regions
Regions can be active or inactive; only active ones are returned by default, but the includeInactive query option surfaces the rest. The fold's division region is active only when the device is folded, and has zero width when flat — inactive regions still support high-level decisions, like preferring an even number of grid columns. Occlusion regions occlude rather than divide, and represent the FaceTime camera.
#### 8:39 - System containers that adapt
Navigation containers like NavigationStack, NavigationSplitView, and TabView provide common navigation patterns, while content containers like List and ScrollView hold your content. Both adapt to the fold for free.
#### 9:20 - Introducing arrangements
A layout container sits between navigation and content containers, arranging two views according to a set of rules called an arrangement. Using the Podcasts Now Playing and transcript views as an example, an arrangement is a function of inputs — size classes, the view's aspect ratio, and any active division regions — to outputs, like whether to show a view and what frame it gets. iOS 27.1 makes system-provided arrangements available in your app.
#### 11:17 - Build with ArrangementView
An ArrangementView takes a primary and a secondary view — here a player view and an up-next view — and goes inside a NavigationStack. In UIKit, use UIArrangementViewController as the root view controller of your UINavigationController, configuring the primary and secondary view controllers.
#### 12:00 - Configure the split arrangement
Set the preferred arrangement with the arrangementViewStyle modifier; the default split style divides its bounds between the primary and secondary views. It splits horizontally when the view is wider than it is tall and vertically when taller. Restrict this with the axes method, and note that when the arrangement can't split along its primary axis it shows only a single view. In UIKit, use the update arrangement method with UISplitArrangement.
#### 13:21 - Use the overlay arrangement
Unlike split, the overlay arrangement prefers positioning content above or below, moving to side by side when the device folds. Query the overlayArrangementZIndex environment property to respond as the user folds and unfolds — useful for switching between collapsed and expanded versions of a view. In UIKit, use the state for view placement method on UIArrangementViewController and read the returned state's Z index.
#### 14:39 - Choose between arrangements
Follow your app's existing patterns: HStack or VStack layouts translate to the split arrangement, ZStack layouts to overlay. Without an existing pattern, choose overlay when there's a clear foreground/background relationship — as in Accessibility Reader, where partially obscuring scrollable content is acceptable — and split when there's a main/detail relationship, as with the Podcasts transcript where neither view should be obscured.
#### 16:09 - When not to use an arrangement
ArrangementViews don't provide navigation infrastructure, so avoid putting navigation containers like NavigationSplitView inside one. Because of how List and ScrollView behave, avoid putting an ArrangementView inside a scrollable container.
#### 16:34 - Next steps
Audit your app's centered layouts and consider whether a two-column layout or a displacement pattern fits. Standard system containers and presentations give you a lot of behavior for free. For custom horizontal split or overlay layouts, consider ArrangementView, and adopt the ReservedRegions API for your highest-priority manually laid out controls.
### Code examples
#### 6:46 - Query reserved regions in SwiftUI
```swift
// SwiftUI
GeometryReader { proxy in
let regions = proxy.reservedRegions(
kind: .division)
}
```
Copy Code
#### 7:03 - Query reserved regions in UIKit
```swift
// UIKit
let regions = view.reservedRegions(
kind: .division)
// Query the frame to incorporate it into your own layout
let frames = regions.map(\.frame)
```
Copy Code
#### 7:22 - Include inactive regions
```swift
// SwiftUI
GeometryReader { proxy in
let regions = proxy.reservedRegions(
kind: .division, options: .includeInactive)
let frames = regions.map(\.frame)
// ...
}
```
Copy Code
#### 8:07 - Query occlusion regions
```swift
// SwiftUI
GeometryReader { proxy in
let regions = proxy.reservedRegions(
kind: .occlusion)
let frames = regions.map(\.frame)
// ...
}
```
Copy Code
#### 11:23 - Add an ArrangementView
```swift
// SwiftUI
var body: some View {
NavigationStack {
ArrangementView {
PlayerView()
} secondary: {
UpNextView()
}
}
}
```
Copy Code
#### 11:26 - Add a UIArrangementViewController
```swift
// UIKit
let arrangementVC = UIArrangementViewController()
let navController = UINavigationController(rootViewController: arrangementVC)
let playerVC = PlayerViewController()
arrangementVC.setViewController(playerVC, for: .primary)
let upNextVC = UpNextViewController()
arrangementVC.setViewController(upNextVC, for: .secondary)
```
Copy Code
#### 12:00 - Specify the split arrangement style
```swift
// SwiftUI
var body: some View {
NavigationStack {
ArrangementView {
PlayerView()
} secondary: {
UpNextView()
}
.arrangementViewStyle(.split)
}
}
```
Copy Code
#### 12:41 - Restrict the split to one axis
```swift
// SwiftUI
var body: some View {
NavigationStack {
ArrangementView {
PlayerView()
} secondary: {
UpNextView()
}
.arrangementViewStyle(
.split.axes(.horizontal))
}
}
```
Copy Code
#### 13:07 - Update the arrangement in UIKit
```swift
// UIKit
let arrangementVC = UIArrangementViewController()
// ...
arrangementVC.updateArrangement(.split.axes(.horizontal))
```
Copy Code
#### 13:26 - Switch to the overlay arrangement
```swift
// SwiftUI
var body: some View {
NavigationStack {
ArrangementView {
UpNextView()
} secondary: {
PlayerView()
}
.arrangementViewStyle(.overlay)
}
}
```
Copy Code
#### 14:07 - Respond to the overlay Z index
```swift
// SwiftUI
enum UpNextMinimization {
case collapsed; case expanded
}
struct UpNextView: View {
@Environment(\.overlayArrangementZIndex)
private var zIndex: Int
var body: some View {
UpNextList(minimization: minimization)
}
var minimization: UpNextMinimization {
zIndex > 0 ? .collapsed : .expanded
}
}
```
Copy Code
#### 14:21 - Read the Z index in UIKit
```swift
// UIKit
let arrangementVC = UIArrangementViewController()
// ...
let primaryState = arrangementVC.state(for: .primary)
myModel.minimization = (primaryState?.zIndex ?? 0) > 0
? .collapsed : .expanded
```
## Source block 3
### Timestamped guidance
#### 0:00 - Introduction
Chris Donegan, an engineering manager in UI Frameworks, and Alex Muller, a system experience engineer, introduce how to take advantage of the unique features of iPhone Duo: responding to the hinge, supporting split view multitasking, and using scene accessories across multiple displays.
#### 0:49 - Respond to the hinge
SwiftUI provides a new onHingeChange modifier and UIKit provides UIHingeInteraction. Both report the high-level hinge status — closed, partially open, and fully open — as well as continuous updates of the hinge angle.
#### 1:18 - Drive a pitch bend with hinge angle
A walkthrough of adding a whammy-bar pitch bend to a playable guitar app. The onHingeChange modifier takes a closure with the previous and current hinge context. Check for a non-null hinge, since null indicates a device without one, and filter for the partially open state — adding an else condition to reset the pitch bend when the angle isn't being read.
#### 2:35 - Hinge data versus layout APIs
Hinge data is observed live and is ideal for driving interactions or effects. For layout, use the arrangement and region APIs covered in "Strike a pose with adaptive layouts on iPhone Duo" instead.
#### 2:59 - Split view multitasking
All apps participate in multitasking on iPhone Duo, where two apps sit side by side. If your app already supports resizing on iPad or iPhone mirroring, you're off to a great start. iPhone Duo also introduces a new layout stacking video and apps together, which your app handles the same way, using tools like size classes and scene geometry.
#### 3:38 - Support multiple scenes
iPhone Duo is the first iPhone to support multiple instances of your app's UI, and apps that support this on iPad will too. One difference: new windows can't be created on the outer display — that's reserved for the inner display. Handle errors when requesting new scenes, and use the UIWindowSceneActivation action, which hides itself automatically when new windows aren't available.
#### 4:22 - Scene accessories
Scene accessories let your app show content on multiple displays at once, pairing additional content with your main UI — like using an iPhone as a controller for a game on an external display. The system dynamically controls their availability; they're enabled by default but can be toggled at any time, so respond to availability changes using observation tracking.
#### 5:00 - The camera capture accessory
New for camera apps on iPhone Duo, CameraCaptureAccessory pairs additional UI on the outer display while your main UI stays on the inner display — useful for showing content to someone while photographing or recording them. It's available when your app is full screen on the inner display with an active camera session, and you register it on the same view as your camera UI.
#### 5:34 - Build a teleprompter accessory
A walkthrough of adding a teleprompter on the outer display of a camera app. The SceneAccessory modifier adds a camera capture accessory to the camera view, so the teleprompter appears only when that view is visible. A toolbar button then toggles the enabled state of the teleprompter model, and the onAvailabilityChange modifier provides a callback to disable that button when the accessory isn't available, such as when the device is closed.
#### 6:44 - Next steps
Update your app to support split view multitasking, use the Hinge API to build impressive interactions and effects, and adopt scene accessories so your app can span multiple displays.
### Code examples
#### 1:33 - Hold pitch bend as state
```swift
struct InstrumentView: View {
/// Normalized bend, 0 is no bend, 1 is deepest bend
@State private var pitchBend: Double = 0
var body: some View {
GuitarView(pitchBend: pitchBend)
}
}
```
Copy Code
#### 1:44 - Add the onHingeChange modifier
```swift
struct InstrumentView: View {
/// Normalized bend, 0 is no bend, 1 is deepest bend
@State private var pitchBend: Double = 0
var body: some View {
GuitarView(pitchBend: pitchBend)
.onHingeChange { _, context in
}
}
}
```
Copy Code
#### 1:57 - Check for a hinge and the partially open state
```swift
var body: some View {
GuitarView(pitchBend: pitchBend)
.onHingeChange { _, context in
// A null hinge means the device doesn't have one
if let hinge = context.hinge, hinge.status == .partiallyOpen {
}
}
}
```
Copy Code
#### 2:10 - Reset the pitch bend
```swift
var body: some View {
GuitarView(pitchBend: pitchBend)
.onHingeChange { _, context in
if let hinge = context.hinge, hinge.status == .partiallyOpen {
}
else {
pitchBend = 0
}
}
}
```
Copy Code
#### 2:17 - Calculate the pitch bend from the hinge angle
```swift
struct InstrumentView: View {
/// Normalized bend, 0 is no bend, 1 is deepest bend
@State private var pitchBend: Double = 0
var body: some View {
GuitarView(pitchBend: pitchBend)
.onHingeChange { _, context in
if let hinge = context.hinge, hinge.status == .partiallyOpen {
pitchBend = calculatePitchBend(angle: hinge.angle)
}
else {
pitchBend = 0
}
}
}
private func calculatePitchBend(angle: Angle) -> Double { ... }
}
```
Copy Code
#### 5:43 - Register a camera capture accessory
```swift
struct CameraRootView: View {
@State private var model = TeleprompterModel()
var body: some View {
CameraView(model: model)
.sceneAccessory {
CameraCaptureAccessory {
TeleprompterView(model: model)
}
}
}
}
```
Copy Code
#### 6:14 - Add a toolbar toggle
```swift
struct CameraRootView: View {
@State private var model = TeleprompterModel()
var body: some View {
CameraView(model: model)
.sceneAccessory {
CameraCaptureAccessory(isEnabled: $model.isEnabled) {
TeleprompterView(model: model)
}
}
.toolbar {
TeleprompterToggle(isEnabled: $model.isEnabled)
}
}
}
```
Copy Code
#### 6:25 - Observe accessory availability
```swift
struct CameraRootView: View {
@State private var model = TeleprompterModel()
var body: some View {
CameraView(model: model)
.sceneAccessory {
CameraCaptureAccessory(isEnabled: $model.isEnabled) {
TeleprompterView(model: model)
}
.onAvailabilityChange { newValue in
model.isAvailable = newValue
}
}
.toolbar {
TeleprompterToggle(isEnabled: $model.isEnabled)
.disabled(!model.isAvailable)
}
}
}
```
## Source block 4
### Timestamped guidance
#### 0:00 - Introduction
Anna from UI Frameworks and Maria, a Human Interface Designer on Apple's design system, introduce how to raise the bar for your app's bars on iPhone Duo.
#### 0:28 - Why bars move to the side
iPhone Duo's wider aspect ratio gives apps more horizontal space. Controls that normally sit at the top and bottom move to the side, preserving vertical space for content and putting controls within easier reach. Their position stays consistent on the inner display in landscape, and returns to a familiar horizontal layout in portrait.
#### 1:29 - Agenda
An overview of what's ahead: orienting bars to a vertical axis, item ordering and how it interacts with containers, tailoring toolbar content for a vertical axis, and managing the overflow menu.
#### 2:00 - Opt in to vertical bars
Rebuild your app against the latest SDKs, then use bars provided by navigation containers. In SwiftUI, pair the toolbar modifier with NavigationStack or NavigationSplitView. In UIKit, prefer UINavigationController and UITabBarController over custom UIToolbar, UINavigationBar, or UITabBar instances, whose content isn't considered.
#### 3:09 - Understand the shared bar region
Navigation, toolbar, and tab bar controls coexist in a shared region — imagine rotating them 90 degrees into a vertical stack. In split views, only the detail column participates and inspectors don't get their own bar. Sheets behave differently per display, and because the bar is aligned with the hardware it stays on the same side in right-to-left languages.
#### 4:29 - Order items in a vertical bar
Keep controls associated with their container and audit your existing configuration. Reserve the top for primary navigation like back or close, followed by prominent actions such as done. Use the cancellation action placement in SwiftUI, or a leading item with leftItemSupplementsBackButton set to false in UIKit. Place prominent actions with topBarPinnedTrailing or pinnedTrailingGroup.
#### 5:56 - Prepare toolbar content
Vertical bars have a fixed width and flexible item height, making them better suited to symbol-only items. You still specify the same icon and title, but the system now also considers whether content suits a vertical or horizontal axis: items with an icon go vertical, while text-only items stay horizontal. Always provide a title, since the system uses it in overflow menus and expanded forms.
#### 8:00 - Control the axis of an item
The new AxisBehavior API adjusts the system's default placement. Keep related items on the same axis — an item that transitions between a symbol and text, like a custom select button, should use the horizontal-only behavior. Custom or complex views stay horizontal by default; set the vertical-preferred behavior when your view does support a vertical representation.
#### 9:00 - Prefer symbol-only items
Minimize title-only items and custom views showing both text and an image so more content can go vertical. A badge can turn a text-and-symbol item into a symbol-only one — adopt the badge API added in iOS 26. Ask whether the text merely reinforces the symbol or carries standalone information; keep controls like a cart button showing a dollar amount in the horizontal bar.
#### 10:07 - Adapt custom views
Custom views need to either fit the bar's fixed width or have a vertically adapted layout, and some metrics may need adjusting. Read the toolbarVerticalEdge environment property or trait to detect a vertical bar. Vertical bars have no scroll edge effect by default but do get a background when reduce transparency is enabled. Flexible spacers are zero size vertically, while fixed spacers respect their minimum.
#### 11:40 - Manage the overflow menu
Items overflow more often on the outer display in landscape, or when competing UI like the keyboard appears. Decide whether your toolbar items or tab bar stay visible longer — toolbars compress first by default, suiting navigation-focused experiences, while task-oriented apps may compress the tab bar. Consolidate any custom overflow into the system menu with ToolbarOverflowMenu or additionalOverflowItems, and reserve the ellipsis for overflow only.
#### 13:10 - Prioritize item visibility
Items overflow from bottom to top by default, but visibility priority gives fine-grained control. Assign high, low, or custom priorities using the visibilityPriority APIs, starting with groups and then items within them. Frequently used actions like Compose or New Note should be among the last to overflow, and controls conveying status such as badged items should remain visible to preserve glanceability.
#### 14:21 - When to opt out
Most apps are good candidates for vertical bars, but a single-page app with a bottom-heavy layout like Calculator may let content expand better horizontally, and a sheet with only one control such as a close button may not warrant the reduced space. Use the toolbarVerticalBehavior and preferredVerticalBar behavior APIs to disable it.
#### 14:53 - Next steps
Build your app with the latest SDKs, audit your bars for the new design, update custom items so they're ready to be placed vertically, and assign overflow priorities so the system can adapt.
### Code examples
#### 2:24 - Use system container toolbars
```swift
// SwiftUI
var body: some View {
NavigationStack {
ContentView()
.toolbar {
ToolbarItem(placement: .bottomBar) {
...
}
}
}
}
```
Copy Code
#### 2:39 - Prefer navigation controllers over custom bars
```swift
// UIKit — content from a custom UIToolbar won't be considered.
// Prefer UINavigationController and UITabBarController,
// which manage their own bars.
let toolbar = UIToolbar()
toolbar.items = [...]
```
Copy Code
#### 5:00 - Place a back or close button
```swift
// SwiftUI
.toolbar {
ToolbarItem(placement: .cancellationAction) {
...
}
}
// UIKit
navigationItem.leftItemsSupplementBackButton = false
navigationItem.leadingItemGroups
= [UIBarButtonItemGroup(...)]
```
Copy Code
#### 5:24 - Pin prominent actions to the trailing edge
```swift
// SwiftUI
.toolbar {
ToolbarItem(placement: .topBarPinnedTrailing) {
...
}
}
// UIKit
navigationItem.pinnedTrailingGroup
= UIBarButtonItemGroup(...)
```
Copy Code
#### 8:08 - Set a preferred axis for a custom view
```swift
// SwiftUI
var body: some View {
ContentView()
.toolbar {
ToolbarItem {
ProfileView()
}
.axisBehavior(.verticalPreferred)
}
}
// UIKit
let item = UIBarButtonItem(customView: ProfileView())
item.axisBehavior = .verticalPreferred
```
Copy Code
#### 8:36 - Keep an item on the horizontal axis
```swift
// SwiftUI
var body: some View {
ContentView()
.toolbar {
ToolbarItem {
SelectOrDoneButton()
}
.axisBehavior(.horizontalOnly)
}
}
// UIKit
item.axisBehavior = .horizontalOnly
```
Copy Code
#### 8:52 - Allow a custom view to go vertical
```swift
// SwiftUI
var body: some View {
ContentView()
.toolbar {
ToolbarItem {
CompassView()
}
.axisBehavior(.verticalPreferred)
}
}
// UIKit
let item = UIBarButtonItem(customView: CompassView())
item.axisBehavior = .verticalPreferred
```
Copy Code
#### 9:27 - Use a badge instead of inline text
```swift
// SwiftUI
var body: some View {
ContentView()
.toolbar {
ToolbarItem(...) {
InboxButton()
.badge(7)
}
}
}
// UIKit
let item = UIBarButtonItem(...)
item.badge = .count(7)
```
Copy Code
#### 10:36 - Read the vertical bar edge
```swift
// SwiftUI
struct ContentView: View {
@Environment(\.toolbarVerticalEdge) var edge
var body: some View {
switch edge {
...
}
}
}
// UIKit
switch traitCollection.verticalBarEdge {
...
}
```
Copy Code
#### 12:23 - Configure toolbar compression behavior
```swift
// SwiftUI
var body: some View {
TabView {
Tab("Recents", systemImage: "clock") {
ContentView()
.toolbarVerticalCompressionBehavior(.prefersToolbarItems)
}
}
}
// UIKit
navigationItem.verticalBarCompressionBehavior = .prefersBarItems
```
Copy Code
#### 12:43 - Consolidate actions into the overflow menu
```swift
// SwiftUI
var body: some View {
ContentView()
.toolbar {
ToolbarOverflowMenu {
Button("Scan") { ... }
Button("Connect") { ... }
}
}
}
// UIKit
navigationItem.additionalOverflowItems = UIDeferredMenuElement({ provider in
provider(self.persistentOverflowItems())
})
```
Copy Code
#### 13:21 - Set item visibility priority
```swift
// SwiftUI
var body: some View {
ContentView()
.toolbar {
ToolbarItem {
Button(...) { ... }
}
.visibilityPriority(.high)
}
}
// UIKit
let item = UIBarButtonItem(...)
item.visibilityPriority = .high
```
Copy Code
#### 14:47 - Disable the vertical bar
```swift
// SwiftUI
var body: some View {
NavigationStack {
ContentView()
.toolbarVerticalBehavior(.disabled)
}
}
// UIKit
class MyViewController: UIViewController {
override var preferredVerticalBarBehavior: UIVerticalBarBehavior {
.disabled
}
}
```
## Source block 5
Source: [Designing for iPhone Duo — Apple Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/designing-for-iphone-duo).
Provenance: text supplied by the user on 2026-09-11. The live page returned a JavaScript shell during retrieval; this section preserves the supplied text rather than claiming an independently fetched page snapshot. Source-page captions and display labels are retained; they do not imply that the corresponding images are bundled with this skill.
### Designing for iPhone Duo
An app designed for iPhone Duo adapts seamlessly to both displays, providing a continuous experience as the device opens and closes.
A stylized representation of an iPhone Duo frame shown on top of a grid. The image is overlaid with rectangular and circular grid lines and is tinted green to subtly reflect the green in the original six-color Apple logo.
iPhone Duo has two displays, each with its own front-facing camera. A hinge in the center lets people open and close the device, and supports a variety of ways to hold and position it. This range of display sizes and poses makes an adaptable layout more important than ever. If your app uses standard system components and you’ve designed it to support resizing, it automatically adapts to the device’s poses with little adjustment required.
Outer display
Inner display
A screenshot of the Home Screen on the outer display of iPhone Duo.
Although iPhone Duo is a new form factor, keep in mind that you’re still designing for iPhone, and Designing for iOS patterns and best practices still apply.
#### Anatomy
iPhone Duo has an inner and an outer display. People interact with the outer display when the device is closed, and the system places toolbars and tab bars on the side to maximize the vertical space for content. The controls remain on the side when the device opens in landscape to ensure a consistent experience as people move between displays.
A center hinge supports a range of ways to hold and position the device. The hinge also impacts the space available for your content as the device folds.
The outer front-facing camera is in the corner and is always visible, vertically aligned with controls on the side. The inner camera is behind the display and stays hidden until the camera is active.
Outer display
Inner display
A diagram of the inner display of iPhone Duo, showing the locations of the hinge and the inner front-facing camera.
#### Device poses
People hold iPhone Duo and set it down in a number of ways: partially folded like a book, placed down on a surface, or standing on its edges.
An illustration of six device poses.
Supporting the device’s various poses doesn’t mean designing a custom layout for each one: instead, use size classes so your app adapts naturally as it changes size. A compact width layout for the outer display and a regular width layout for the inner display give you the fundamentals for every pose. Don’t reinvent your app when it resizes; allow the existing layout to expand based on the available space instead. See Dynamic layouts for guidance.
#### Best practices
Build your app to resize. Because the device has two displays and supports a wide range of poses and Split View multitasking, your app can appear at many different sizes. Use size classes, layout margins, and safe area insets to lay out controls and content. Avoid fixed widths and display-specific dependencies. See Dynamic layouts below and Layout for guidance.
Create a consistent experience across displays. Keep functionality and the state of elements the same between displays. Maintain your app’s information hierarchy, but show an additional level of hierarchy on the larger inner display if it makes sense for your content. Mail, for example, shows either a list of emails (primary) or an email (secondary) when the device is closed. When it’s open, it shows both side by side.
Outer display
Inner display
A screenshot of Mail on the outer display of iPhone Duo, showing the contents of an email.
Maintain the same functionality across device poses. Controls may overflow and content may move or change size as the interface adapts to the available area. Provide access to the same controls and content regardless of how someone holds or views the device. For guidance, see Dynamic layouts and Vertical controls.
Follow the system’s vertical layout for toolbars, tab bars, and navigation controls. Because the outer display is wider and shorter than the display on other iPhone devices, the system moves controls to the side to preserve vertical space for content and reflect the asymmetry of the display. On the inner display, controls remain on the side in landscape to preserve a continuous experience at the same vertical height. If you use standard system components, you receive this layout automatically, but you may want to refine it based on the needs of your app. For guidance, see Vertical controls.
Make your game playable in every device pose. You can choose to lock to either portrait or landscape orientation, but be sure to fill the screen as the device pose changes. When resizing, keep text and control sizes as consistent as possible. Prefer changing the aspect ratio over letterboxing or pillarboxing in games; if you can’t avoid letterboxing or pillarboxing, add artwork to the padding area to help the experience feel full screen. See Designing for games for additional guidance.
#### Dynamic layouts
Designing for iPhone Duo means accounting for a variety of hardware and software configurations. As with all iOS devices, build your layouts with layout margins and safe area insets, and steer clear of fixed widths or anything tied to a specific display.
For guidance, see Layout. For margins and safe areas, see Apple Design Resources. For developer guidance, see safeAreaInsets (SwiftUI) and safeAreaInsets (UIKit).
##### Reserved regions
In addition to standard considerations for safe areas, available space on iPhone Duo is shaped by reserved regions. These represent areas within the display that content avoids covering, or that components adapt to accommodate. These are familiar if your layout adapts to similar areas on other platforms, such as the window controls on iPad.
The reserved regions on iPhone Duo include:
The outer front-facing camera. This region is always present, and expands into the Dynamic Island for Live Activities. When controls are on the side, the system automatically accounts for it and arranges elements accordingly.
The inner front-facing camera. This region is only present when the camera is active. When it’s inactive, the camera isn’t visible; when the camera activates, the UI moves aside to indicate the presence of the camera.
The folding region. This region is conditional based on how a person uses the device. When the device is partially open, the folding region divides the inner display into multiple usable regions, excluding the region at the center as the display folds.
Outer display
Inner display
A diagram of the outer display of iPhone Duo, showing the location of the outer camera region.
Many system components automatically adapt to reserved regions. Components like alerts, context menus, and sheets automatically move to account for the fold, while larger components like split views adapt their columns’ width and margins to match the symmetry of the inner display. For custom components, the reserved region APIs provide a way to reposition content away from reserved regions.
Adapt your layout when the device folds. Prefer a layout container that adapts automatically, like the split view in Notes that adjusts the width of each pane to stay clearly visible as the device folds. In a grid-style layout, prefer an even number of columns so content divides cleanly. Use the reserved region APIs to keep important elements clear of the center if the system doesn’t move them automatically.
Fully open
Partially folded
A screenshot of the Notes app on the inner display of iPhone Duo, representing the display when fully open. The leading pane shows a list of notes and is narrower than the trailing pane, which shows the contents of a note.
Avoid extreme layout changes as people fold the device. Move only what’s necessary to keep elements visible and easy to tap. Controls that disappear or shift dramatically are harder to find and track, so favor small adjustments over rearrangement.
##### Split views
On iPhone Duo, a split view expands on the inner display and collapses to a single pane on the outer display, the same way it adapts between regular and compact environments on other iPhone devices. When built with standard components, split views adapt to reserved regions automatically, adjusting width and margins to adapt to the fold.
For general guidance, see split views. For developer guidance, see NavigationSplitView (SwiftUI) and UISplitViewController (UIKit).
##### Arrangement views
An arrangement view is a layout container that holds two views inside it — a primary view and a secondary view — and dynamically organizes them based on display size, orientation, and reserved regions.
There are two types of arrangement view: split and overlay.
A split arrangement divides its area between its primary and secondary views. It splits horizontally when the arrangement is wider than it is tall, and splits vertically when the arrangement is taller than it is wide.
An overlay arrangement positions the primary and secondary views on top of one another. When the display is partially folded, the views move to occupy each side; otherwise the primary view moves atop the secondary view.
Split arrangement
Overlay arrangement
A diagram of a split arrangement on the inner display of iPhone Duo. A secondary view fills the leading half of the display, and a primary view fills the trailing half.
You can limit which axes a split arrangement uses, and collapse the secondary view in an overlay arrangement when you don’t want it to appear.
Consider an arrangement view when your layout already resembles one. A layout that places two views side by side or one above the other, such as an HStack or VStack, translates directly to a split arrangement. A layout that layers one view over another, such as a ZStack, translates to an overlay arrangement.
Keep navigation outside of arrangement views. An arrangement view lays out content but doesn’t handle navigation, so place navigation containers like navigation split views and tab views around it rather than within it.
#### Vertical controls
On iPhone Duo, toolbars, tab bars, and navigation controls that are typically at the top and bottom of the display move to the side, preserving vertical space for content and keeping controls within easy reach. The exception is the inner display in portrait, which has enough vertical space to keep standard horizontal bars.
Controls on the side include both system and app elements: the Dynamic Island, the status bar, the toolbar (including navigation buttons), and the tab bar.
A diagram of the outer display on iPhone Duo. Vertical elements on the trailing edge are labeled with callouts indicating the position of the Dynamic Island, status bar, toolbar, and tab bar respectively, from top to bottom.
When two apps share the inner display with Split View multitasking, each one places controls along its outer edge, so the left app has controls on the left.
A diagram of two apps open in Split View multitasking on the inner display of iPhone Duo. The left and right edges of the display each have callouts indicating the area for controls on the vertical axis, and callouts indicating their corresponding apps.
Because controls on the vertical axis stay aligned with the hardware, they hold the same position relative to the camera on the outer display, and stay on the same side in right-to-left languages.
Account for asymmetry in your layouts. Because controls sit along one edge, the space for content is asymmetrical. Use safe areas to make sure controls don’t cover your content, including controls on the opposite edge, like when two apps share the inner display with Split View multitasking.
Keep controls consistent across device poses. Because not every pose places controls vertically on the side, and there isn’t always the same amount of space available, it’s important to keep controls’ relative positions as similar as possible so people don’t have to relearn where actions live as they change between poses.
Follow the standard placement order for toolbar items. Reserve the top of the vertical axis for primary navigation controls, like Back or Close, followed by prominent actions, like Done. This preserves familiar navigation patterns while keeping important actions within reach. Keep remaining toolbar items in their original groupings; the system provides a vertical space between items from the top and bottom bars to keep them distinct.
Prioritize frequently used toolbar items to keep them easily available. Items overflow from bottom to top by default. Assign each item a visibility priority to change that order, starting with whole groups and then individual items within a group if you need finer control. For developer guidance, see ToolbarItemVisibilityPriority (SwiftUI) or UIBarButtonItemVisibilityPriority (UIKit).
Preserve frequently used actions first, like Compose in Mail or New Note in Notes, and keep controls that convey important status, like items with badges, visible longer so people can see them at a glance.
In general, don’t override the default bar placement. The position of controls on the vertical axis is one of the core patterns of iPhone Duo. Keeping controls in familiar positions helps people get to know how your app works right away, and reinforces the unified platform experience.
Consider using the full display width for interfaces where bars aren’t necessary. Some layouts can span the full display, which works well for visual, immersive interfaces that don’t scroll, as long as nothing conflicts with the Dynamic Island or the status bar. Calculator, for example, occupies the full width of the display. You can also combine both approaches, letting a background image or header span the full width while scrollable content stays inset.
Screenshots of Calculator on iPhone 16 in portrait (left) and the outer display of iPhone Duo (right). The layout for iPhone 16 places buttons in four columns of five items each, while the layout for iPhone Duo places buttons in five columns of four items each.
Group related toolbar items instead of spacing them manually. Groups you create with ToolbarItemGroup (SwiftUI) or UIBarButtonItemGroup (UIKit) provide space between items and other groups automatically, and adapt as the available space changes, so avoid adding fixed spacing yourself. For guidance, see Toolbars.
Locate controls near the content they affect. When controls belong to a content area other than the one along the trailing edge, keep them with that area rather than moving them to the side. Proximity makes the relationship between controls and content clear. For example, controls that affect the list of emails in Mail stay above the leading pane to indicate that they apply to the list, rather than the contents of an individual email.
A screenshot of Mail on the inner display of iPhone Duo, with tint colors overlaid to indicate the leading and trailing panes. Callouts indicate the location of controls for the leading pane, placed directly at the top of the pane, and controls for the trailing pane, placed vertically on the trailing edge.
Provide both a title and a symbol for each toolbar item that isn’t text-only. Giving both lets the system pick the right representation for the context. Include a title even when an item shows a symbol, because the system uses the title in overflow menus and expanded forms. For developer guidance, see Label (SwiftUI) and UIBarButtonItem (UIKit).
Keep text-based buttons to a minimum. Labels that include text stay in a horizontal bar, so prefer a symbol wherever one works.
When space is limited, preserve either the toolbar or tab bar based on the experience that the view provides. In navigation-focused experiences, move toolbar items into the overflow menu so the tab bar and primary destinations remain accessible. This is the default bar compression behavior.
In task-oriented experiences, minimize the tab bar to preserve the toolbar actions that are central to completing the task. This mirrors the minimized tab bar behavior present on other iPhone devices.
Toolbar compressed
Tab bar compressed
A diagram of the outer display of iPhone Duo in landscape, with a callout indicating the full tab bar and a callout indicating toolbar items collapsed into the overflow menu.
Use the system overflow menu. If your app has its own overflow menu, move those actions into the system menu so people find everything in one place. Reserve the ellipsis symbol for overflow, and give other menus a distinct symbol. For developer guidance, see ToolbarOverflowMenu (SwiftUI) and additionalOverflowItems (UIKit).
WHAT IT HELPS WITH
Help your app adapt.
Make room for every pose.
Help your layouts adapt as the available space changes.
Work around the fold.
Keep content and controls visible, comfortable, and within reach.
Go beyond one display.
Explore hinge interactions, multitasking, and experiences across displays.
Put controls in their place.
Adapt navigation and toolbars while keeping key actions accessible.
PUT IT TO WORK
Add context.
Then start building.
Copy iPhone Duo Kit into your coding assistant’s context, or download SKILL.md and add it to your agent’s skills folder. Then ask it to inspect your app and implement the changes it needs for iPhone Duo.
An independent resource based on Apple’s developer guidance, with instructions to preserve API names and flag missing details.
KEEP EXPLORING