View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • AI 与机器学习
    • App Intents
    • Apple 智能
    • 游戏
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于

更多视频

  • 简介
  • 概要
  • 代码
  • Strike a pose with adaptive layouts on iPhone Duo

    Learn how to create responsive, flexible layouts that work great on iPhone Duo. Explore displacement design patterns that keep content visible and reachable as people open and close their iPhone Duo. Discover how to use arrangement views in SwiftUI and UIKit to build split and overlay presentations, and find out how to query reserved regions to tailor layouts around the hinge and cameras.

    章节

    • 0:00 - Introduction
    • 0:27 - Reserved regions on iPhone Duo
    • 1:29 - Designing around the hinge
    • 2:26 - Displacement patterns
    • 4:00 - Choose where content moves
    • 5:12 - Adapt content to its new region
    • 6:39 - Query reserved regions
    • 7:50 - Division and occlusion regions
    • 8:39 - System containers that adapt
    • 9:20 - Introducing arrangements
    • 11:17 - Build with ArrangementView
    • 12:00 - Configure the split arrangement
    • 13:21 - Use the overlay arrangement
    • 14:39 - Choose between arrangements
    • 16:09 - When not to use an arrangement
    • 16:34 - Next steps

    资源

      • 高清视频
      • 标清视频

    相关视频

    Tech Talks

    • Leverage multiple displays and scenes on iPhone Duo
    • Raise the bar with iPhone Duo
  • 搜索此视频…
    • 6:46 - Query reserved regions in SwiftUI

      // SwiftUI
      GeometryReader { proxy in
        let regions = proxy.reservedRegions(
          kind: .division)
      }
    • 7:03 - Query reserved regions in UIKit

      // UIKit
      let regions = view.reservedRegions(
        kind: .division)
      
      // Query the frame to incorporate it into your own layout
      let frames = regions.map(\.frame)
    • 7:22 - Include inactive regions

      // SwiftUI
      GeometryReader { proxy in
        let regions = proxy.reservedRegions(
          kind: .division, options: .includeInactive)
      
        let frames = regions.map(\.frame)
        // ...
      }
    • 8:07 - Query occlusion regions

      // SwiftUI
      GeometryReader { proxy in
        let regions = proxy.reservedRegions(
          kind: .occlusion)
      
        let frames = regions.map(\.frame)
        // ...
      }
    • 11:23 - Add an ArrangementView

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            PlayerView()
          } secondary: {
            UpNextView()
          }
        }
      }
    • 11:26 - Add a UIArrangementViewController

      // 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)
    • 12:00 - Specify the split arrangement style

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            PlayerView()
          } secondary: {
            UpNextView()
          }
          .arrangementViewStyle(.split)
        }
      }
    • 12:41 - Restrict the split to one axis

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            PlayerView()
          } secondary: {
            UpNextView()
          }
          .arrangementViewStyle(
            .split.axes(.horizontal))
        }
      }
    • 13:07 - Update the arrangement in UIKit

      // UIKit
      let arrangementVC = UIArrangementViewController()
      
      // ...
      
      arrangementVC.updateArrangement(.split.axes(.horizontal))
    • 13:26 - Switch to the overlay arrangement

      // SwiftUI
      var body: some View {
        NavigationStack {
          ArrangementView {
            UpNextView()
          } secondary: {
            PlayerView()
          }
          .arrangementViewStyle(.overlay)
        }
      }
    • 14:07 - Respond to the overlay Z index

      // 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
        }
      }
    • 14:21 - Read the Z index in UIKit

      // UIKit
      let arrangementVC = UIArrangementViewController()
      
      // ...
      
      let primaryState = arrangementVC.state(for: .primary)
      myModel.minimization = (primaryState?.zIndex ?? 0) > 0
        ? .collapsed : .expanded
    • 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.

开发者页脚

  • 视频
  • Tech Talks
  • Strike a pose with adaptive layouts on iPhone Duo
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • AI 与机器学习
    • Apple 智能
    • 音频与视频
    • 增强现实
    • 商务
    • 设计
    • 分发
    • 教育
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 安全性
    • Safari 浏览器与网页
    打开菜单 关闭菜单
    • 文档
    • 下载
    • 示例代码
    • 视频
    • 文档归档
    打开菜单 关闭菜单
    • 帮助指南与文章
    • 联系我们
    • 论坛
    • 反馈与错误报告
    • 系统状态
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件
    • “反馈助理”
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • 安全赏金计划
    • Security Research Device Program
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Academy
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App,并在 bilibili 和微信上关注我们。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则