為 iPhone Duo 設計
概述
來源:Apple 人機介面指南,「為 iPhone Duo 設計」(新頁面,2026 年 9 月 9 日)。 https://developer.apple.com/design/human-interface-guidelines/designing-for-iphone-duo
核心原則:一個能在兩個螢幕和多種姿勢間流暢調整大小的 App。不要為每種姿勢設計佈局;請使用 Size Classes(緊湊寬度 = 外螢幕,常規寬度 = 內螢幕),並讓標準系統元件進行適應。所有正常的 iOS HIG 仍然適用。
當你需要確切措辭或某規則的開發者 API 時,請擷取上述頁面。
硬體簡介
外螢幕(闔上時使用):比其他 iPhone 更寬但更短,相機固定在一個角落且始終可見。內螢幕(打開時使用):相機隱藏在螢幕下方,直到啟用時才顯示。中央鉸鏈允許書本式、平放和邊緣直立等姿勢。除內螢幕的直向模式外,工具列、標籤列、狀態列和 Dynamic Island 都位於側邊(垂直軸)。
快速檢查清單
佈局
- 構建可調整大小:Size Classes、佈局邊距、安全區域插入。沒有固定的寬度,也不與任何單一螢幕綁定。
- 在兩個螢幕和每個姿勢上保持相同的功能與狀態。內螢幕可以增加一個額外的層級(例如郵件 App:闔上時顯示列表或訊息,打開時兩者並排顯示)。
- 尊重預留區域:外螢幕相機(始終存在,會擴展為 Dynamic Island)、內螢幕相機(僅在啟用時)、折疊區域(僅在部分打開時)。對於自訂元件,使用
ReservedRegion(SwiftUI) /UIView.ReservedRegion(UIKit)。 - 折疊時:偏好自適應容器(分割視圖會均衡面板寬度),使用偶數格的網格列數,進行小幅調整,絕不做戲劇性的重新排列。
- 分割視圖:在內螢幕上展開,在外螢幕上自動摺疊為一個面板。
- 排列視圖 (
ArrangementView/UIArrangementViewController):兩個視圖,主要 + 次要。分割(並排或堆疊,類似 HStack/VStack 佈局)或 疊加(分層,類似 ZStack 佈局)。將導航容器保留在它們外部。
垂直控制項
- 保持系統的側邊放置;通常不要覆蓋它。
- 內容區域是不對稱的:使用安全區域,以便側邊控制項(包括分割視圖中另一個 App 的控制項)絕不會遮蓋內容。在從右到左的語言中,控制項保持在同一側。
- 工具列順序,從上到下:主要導航(返回、關閉),然後是突出操作(完成),接著是剩餘的群組。
- 溢位預設從下到上;設定可見性優先級(
ToolbarItemVisibilityPriority/UIBarButtonItemVisibilityPriority),以便頻繁操作(如撰寫、新建筆記)和有徽章的项目保持可見。 - 使用
ToolbarItemGroup/UIBarButtonItemGroup對項目進行分組;絕不添加手動的固定間距。 - 每個非文字的工具列項目都同時具有標題和符號。盡量減少純文字按鈕(它們會保留在水平欄中)。
- 空間緊張時:以導航為主的視圖會將工具列壓縮到溢位(預設);以任務為主的視圖則會最小化標籤列(
ToolbarVerticalCompressionBehavior/UIVerticalBarCompressionBehavior)。 - 使用系統溢位選單;省略號僅用於溢位。
- 屬於非尾端面板的控制項應保留在該面板旁邊(例如郵件列表控制項保持在列表上方)。
- 沉浸式、非滾動的 UI 可以橫跨全寬,前提是沒有任何內容與 Dynamic Island 或狀態列衝突(例如計算機 App 可以是 5 列 x 4 行)。
遊戲
- 在每個姿勢下都可遊玩。鎖定方向是可以的,但必須填滿螢幕。保持文字和控制項大小一致。偏好改變長寬比而非使用信箱/郵筒模式;如果無法避免,請用藝術圖案填充邊框。
來自 Apple 技術講座
HIG 頁面未說明的三個 Duo 技術講座細節(111466 Design for iPhone Duo,111462 Raise the bar with iPhone Duo,111463 Strike a pose with adaptive layouts)。
需考慮的系統行為
- 外螢幕:控制項位於右側以便右手拇指觸及。Dynamic Island 會隨著 Live Activities 的到來垂直擴展,並與 App 欄共享側邊條。空間不足時,App 項目會自動摺疊到溢位中。
- 部分折疊(書本式):文字、圖片和互動元素會遠離彎曲處。在直向折疊模式下,互動元素會移到下半部。
- 分割視圖多工處理:使用主畫面手勢將 App 拖曳到側邊,形成對等的 50/50 分割。每個 App 的控制項位於其外側邊緣。
- 子母畫面可以固定到頂部;下方的 App 會垂直調整大小,折疊時影片會填滿一半螢幕。
- 工作表:在外螢幕上,工作表工具列會變成垂直放置。在內螢幕上,工作表會居中顯示並帶有水平工具列。折疊時,工作表會滑離折疊處。使用
preferredPlacement時,放置在左側的工作表沒有垂直工具列,而放置在右側的則會有。 - 內建的折疊迴避功能(工作表、提示、選單、工具列按鈕等)會將互動元素推離折痕。可滾動內容不需要避開折疊處。
選擇使用垂直工具列
- 使用最新 SDK 重新建置。
- 使用導航容器擁有的工具列:SwiftUI 中
NavigationStack、NavigationSplitView或TabView上的.toolbar;UIKit 中設定在UINavigationController/UITabBarController內視圖控制器上的項目。自訂的UIToolbar/UINavigationBar/UITabBar內容不會被移動。
- 只有位於顯示邊緣的容器才會變成垂直工具列。在分割視圖中,只有詳細資訊欄會如此;檢查器不會有自己的垂直工具列。
- 映射:頂部工具列項目移到條的頂部,底部項目移到條的底部,而標籤列保持底部對齊。彈性間距的高度為零;固定間距保持其大小。
- 返回/關閉:使用導航控制器時會自動處理。自訂的返回/關閉按鈕使用
.cancellationAction(SwiftUI) 或帶有leftItemSupplementsBackButton = false的前導項目 (UIKit)。突出的操作使用topBarPinnedTrailing(SwiftUI) 或pinnedTrailingGroup(UIKit)。
哪些變垂直,哪些保持水平
- 垂直工具列有固定的寬度和可變的高度,因此適合純符號項目。有圖示的項目會變成垂直;純文字項目(如「編輯」、分段控制項、寬文字按鈕)則保留在水平導航欄中。
- 使用新的 AxisBehavior API 進行覆蓋:對於在符號和文字之間變化的項目(例如自訂的選擇器;系統的「編輯」按鈕會自行處理),使用水平僅限模式;對於具有垂直形式的自訂視圖(例如指南針),使用垂直偏好模式。
- 將文字和符號項目轉換為僅符號並帶有徽章(iOS 26 徽章 API),例如收件箱計數。如果文字攜帶重要資訊(例如購物車總額),則保留文字。
- 鍵盤配件列保持附加在鍵盤上。
- 自訂視圖:適合固定寬度或提供垂直佈局。讀取
toolbarVerticalEdge(環境值或特徵),當工具列無法垂直放置時其值為 nil。 - 垂直工具列預設沒有滾動邊緣效果。它們僅在開啟「減少透明度」時才獲得背景,因此自訂內容必須在兩種情況下都保持清晰可讀。
- 要選擇退出(例如像計算機這樣的單頁、底部較重的 App,或只有關閉按鈕的工作表),使用
toolbarVerticalBehavior/preferredVerticalBarBehavior。沒有垂直工具列的工作表會正好在相機前停止。 - 每個視圖的壓縮:
toolbarCompressionBehavior。可見性優先級可以設定為高、低或自訂;先按群組設定,然後再按項目設定。
佈局模式
- 外螢幕:大多數內容需要偏移,以免被控制項遮擋,而對齊水平安全區域插入可以為你做到這一點。僅對於沉浸式、非滾動的 UI,且沒有互動元素位於工具列下方時,才將內容居中於整個顯示器。折衷的方法是使用全寬背景搭配插入的滾動內容,並將所有互動元素保留在插入區域內。
- 內螢幕,為了不讓它只是一個拉伸的手機 App:使用分割視圖、在寬螢幕時變成 2 欄的堆疊佈局(如音樂 App),或者對於資訊密集的 App,將標籤列顯示為側邊欄(如健康 App)。
- 可選的桌面(筆電)姿勢佈局:媒體在頂部,控制項在穩定的下半部。它必須保留所有控制項和相同的層級結構。
- 位移:將元素移出預留區域,並移入適合其用途的區域。選擇範圍:如果元素獨立則單獨移動,將相關元素一起移動,並且不要將元素移動到離其來源太遠的地方。在書本姿勢下,提示會移動到尾側,靠近它們在關閉時會重新出現的位置。在桌面姿勢下,可一覽的內容放在頂部,可點擊的控制項放在底部。搜尋列保持在它搜尋的視圖上方。對於網格,保留外邊距並在鉸鏈處加寬間距(如健身 App)。
- 系統分割視圖在折疊時會均衡為 50/50(如提醒事項 App)。
預留區域 API
- SwiftUI:
GeometryProxy上的reservedRegion(來自GeometryReader或onGeometryChange)。UIKit:UIView上的reservedRegion。使用.frame進行佈局。 - 有兩種區域。分割區域(折疊處)僅在折疊時啟用,平放時寬度為零。遮擋區域(內置 FaceTime 相機)僅在相機開啟時啟用。
- 預設返回啟用的區域;使用
includeInactive來預先規劃(例如,每當存在分割區域時,選擇偶數的欄數)。 - 對於以相機為中心的 App,將關鍵內容和控制項保持遠離內置相機。
- 將折疊狀態作為互動輸入的內容涵蓋在講座 Leverage multiple displays and scenes on iPhone Duo 中,此技能不包含該內容。
排列視圖 (iOS 27.1)
- SwiftUI:在
NavigationStack內部使用ArrangementView(primary, secondary),並以.arrangementViewStyle(.split)(預設)或.overlay設定樣式。使用.split.axes(...)限制分割方向;如果無法沿主軸分割,則只顯示主要視圖。 - UIKit:
UIArrangementViewController作為導航控制器的根視圖,搭配updateArrangement和UISplitArrangement。 - 疊加模式:平放時堆疊,折疊時並排。讀取
overlayArrangementZIndex(SwiftUI) 或state(for:)後接.zIndex(UIKit),以在摺疊和展開的次要視圖之間切換。 - 選擇:遵循現有模式(HStack/VStack 變成 split,ZStack 變成 overlay)。否則,對於前景/背景關係(部分遮擋可滾動內容是可接受的,例如輔助使用朗讀器),使用 overlay;對於主從關係(兩個視圖都不應被遮擋,例如 Podcasts 逐字稿),使用 split。
- 不要將導航容器放在 ArrangementView 內部,也不要將 ArrangementView 放在
List/ScrollView內部。
就緒審計(來自講座)
- 使用最新 SDK 重新建置。
- 審計工具列:系統容器、項目順序、帶標題的符號。
- 使自訂項目適應垂直工具列。
- 設定溢位優先級。
- 審計居中佈局:每個佈局是否應變成 2 欄、進行位移或使用 ArrangementView?
- 對高優先級、手動佈局的控制項採用預留區域 API。
Duo 工藝層(來自 apple-design 技能)
HIG 說明了什麼需要適應。本節將 Apple 的流暢介面與設計原則指導(WWDC Designing Fluid Interfaces,Principles of Great Design)應用於它在 Duo 上的感受。這些是應用的原則,而非 HIG 規則。如需完整的動畫工具包(投影、橡皮筋效果、速度交接),請同時載入 Emil Kowalski 的 apple-design 技能(來自 emilkowalski/skills),並將其網頁範例轉換為 SwiftUI/UIKit。
折疊與大小調整動畫
- 折疊是一個連續的、由使用者驅動的手勢。隨之而來的佈局變化(面板寬度均衡、網格重新排列、內容移出折疊區域)應平穩地跟隨鉸鏈,並且必須可中斷:使用者可以在折疊中途停止或反向,因此始終從螢幕上的當前值開始動畫,切勿快照到結束狀態。
- 對重新排列使用臨界阻尼彈簧(SwiftUI 的
.spring(duration: 0.4, bounce: 0)或.smooth;UIKit 的UIView.animate(springDuration:bounce:)搭配bounce: 0)。無回彈:使用者並未輕拂任何東西,因此過衝會顯得像故障。 - 跨螢幕的空間一致性:當有人打開裝置時,他們在外螢幕上查看的項目應保持為錨點(例如郵件 App 中打開的電子郵件成為尾側面板,而非一個新畫面)。保持滾動位置和選取狀態;額外的層級結構會出現在其旁邊。
- HIG 中的「小幅調整勝於重新排列」與「預示變更方向」是同一規則:元素應明顯滑向它們的新位置,而非瞬間移動。
側邊控制項作為材質層
- 側邊工具列和標籤列浮動在內容之上,預設沒有滾動邊緣效果也沒有背景(根據技術講座)。不要添加硬分隔線或你自己的背景;使用安全區域插入,確保內容不會被工具列遮擋。
- 放置在工具列中的自訂視圖必須在其後方內容滾動時保持清晰可讀,並且在「減少透明度」開啟時出現的實色背景上也要清晰可讀。
映射到 Duo 的原則
- 熟悉性:不要覆蓋垂直工具列的放置位置;這是平台新的肌肉記憶。
- 分組與映射:控制項保持在其影響的面板旁邊(郵件列表控制項在列表上方)。
- 尋路:在每個姿勢中,使用者都應該能回答「我在哪裡,如何返回」。返回/關閉始終位於垂直軸的頂部。
- 靈活性:一個適應性佈局,動態字體會隨之縮放。在具有側邊工具列的窄高外螢幕上測試最大的文字大小。
- 回應性:姿勢改變絕不能封鎖輸入。折疊期間的點擊仍應被觸發。
無障礙
- 開啟「減少動態效果」時,用簡短的淡入淡出取代重新排列的滑動/彈簧效果。
- 開啟「減少透明度」時,側邊工具列變為實色。
- 折疊期間移動的大面積表面:保持動畫簡短,避免大的亮度跳躍。
常見錯誤
| 錯誤 | 修正 |
|---|---|
| 為每種姿勢使用自訂佈局 | 使用 Size Classes 搭配可調整大小的佈局 |
| 隱藏功能 | ... |