Embed the Photos Picker in your app
Media & Web 进阶 20m

将系统照片选择器嵌入你的 App

Embed the Photos Picker in your app

2023年6月5日

在 Apple 官方观看视频

一句话判断

iOS 17 让你把系统的 Photos Picker 直接嵌入 App 界面,配合 continuous selection 模式实现实时选图,再也不需要自建相册浏览器。

这场 Session 讲了什么

Justin 从 Photos 团队出发,介绍了 Photos Picker 在 iOS 17 中的重大增强:

嵌入式选择器。之前 Photos Picker 只能以 modal sheet 方式弹出。iOS 17 新增 .photosPickerStyle(.inline) 修饰符,让它直接嵌入你的 SwiftUI 视图中。即使嵌入,它仍然在独立进程中渲染,App 无法直接访问未选中的照片。

三种样式.presentation(默认的 sheet 模式)、.inline(嵌入模式,占满指定区域)、.compact(单行横向滚动模式,适合空间受限的 UI)。

连续选择。设置 selectionBehavior: .continuous 后,用户每次选择/取消选择都会实时通知 App,不需要点击”添加”按钮确认。这让嵌入模式下的体验变得非常流畅。

配件控制。可以隐藏导航栏、工具栏、搜索栏等 UI 元素,也可以禁用特定功能(如搜索、相册导航、暂存区),然后用你自己的 UI 替代。

隐私透明度。首次展示嵌入式选择器时,系统自动弹出说明 UI,告知用户 App 只能访问被选中的照片。选择器上有隐私徽章标识其独立进程属性。

值得深挖的点

独立进程渲染的边界。嵌入的选择器看起来像是你 App 的一部分,但它实际上运行在独立进程中。你的 App 不能截图选择器内容,不能程序化控制选择器的滚动或点击。只有用户主动选择的资产才会传递给你的 App。

compact 样式的使用场景。单行选择器适合消息输入框上方的附件栏、笔记 App 的插图区域等纵向空间有限但需要展示照片选项的 UI。

UIKit 和 AppKit 的对应 API。同样的能力通过 PHPickerConfiguration 提供,支持 selection: .continuousmode: .compactedgesWithoutContentMarginsdisabledCapabilities 等属性。需要作为 child view controller 添加。

代码片段

// 嵌入式 Photos Picker 完整配置
PhotosPicker(
    selection: $selectedItems,
    matching: .images,
    photoLibrary: .shared()
) {
    // 自定义选择器触发按钮(presentation 模式)
    Text("选择照片")
}
.photosPickerStyle(.inline)  // 嵌入模式
.photosPickerAccessoryVisibility(.hidden, edges: .all)  // 隐藏导航栏和工具栏
.photosPickerDisabledCapabilities(.selectionActions)  // 隐藏取消和添加按钮
.ignoresSafeArea()  // 让选择器扩展到屏幕底部边缘
.frame(height: 300)  // 固定高度
// 连续选择模式:实时接收选中的照片
@State var selectedItems: [PhotosPickerItem] = []
@State var selectedImages: [UIImage] = []

// 使用 onChange 监听选择变化
.onChange(of: selectedItems) { newItems in
    Task {
        for item in newItems {
            if let data = try? await item.loadTransferable(type: Data.self),
               let image = UIImage(data: data) {
                selectedImages.append(image)
            }
        }
    }
}

最佳实践

  • 用系统 Photos Picker 替代自建相册浏览器,获得搜索、缩放网格等免费功能。
  • 嵌入模式配合 continuous selection 和隐藏配件按钮,可以实现完全定制的外观。
  • compact 样式适合空间受限的 UI,但别忘了处理横向滚动的交互。
  • 尊重隐私徽章和引导 UI 的展示,不要试图绕过它们。
  • 处理 HDR 照片和 Cinematic 模式视频时,注意配置正确的 PHPickerConfiguration 选项。

还有什么值得关注

  • “What’s new in privacy” Session 讲了照片权限提示的变更
  • 系统选择器支持搜索和缩放网格,这些功能不需要你自己实现
  • UIKit/AppKit 的对应 API 让非 SwiftUI 项目也能使用嵌入模式
  • 选择器自动处理 Safe Area,配合 .ignoresSafeArea() 可以扩展到屏幕边缘
WWDC 2023