
-
利用拍摄控件提升你的相机体验
了解如何为你的相机体验自定拍摄控件。我们将向你展示如何使用各种实体拍摄控件 (包括新增的 AirPods 支持) 拍摄照片,以及如何使用相机控制来调整设置。
章节
- 0:00 - 简介
- 2:51 - 实体拍摄
- 3:01 - 事件处理
- 6:39 - AirPods 远程拍摄
- 10:00 - 详细控制
资源
- Accessing the camera while multitasking
- AVFoundation
- AVMultiCamPiP: Capturing from Multiple Cameras
- Capture setup
- Capturing Photos with Depth
- Creating a camera experience for the Lock Screen
- Creating a camera extension with Core Media I/O
- DockKit
- Forum: Photos & Camera
- Scanning data with the camera
- Supporting Continuity Camera in your macOS app
- Supporting Continuity Camera in your tvOS app
相关视频
WWDC24
WWDC23
-
搜索此视频…
大家好 我叫 Vitaliy 我是 AVKit 团队的工程师 欢迎观看“利用 Capture Controls 提升你的相机体验” 在这个讲座中 我们将探索可通过哪些强大的新方式 来改善 App 中的用户交互 借助 Capture Controls 你可以通过编程方式将实体 按钮手势映射到相机操作 让用户获得与 iOS 原生 “相机”App 一致的熟悉感受 我们还将展示 iOS 26 中推出的 一项令人惊叹的新功能 相信你一定会喜欢
为了展示 Capture Controls 的 强大功能 让我们以 iOS 中的 “相机”App 为例 我们不再使用 屏幕上的 UI 按钮拍照 而是改用手机上的实体按钮
只需点按调高音量按钮 即可启动拍摄
但这个 API 不仅支持点按 还支持长按 例如 在相机模式下 按住调低音量按钮 可以启动视频录制
差不多就是这样 通过 Capture Controls 我们为用户提供了 更加灵活的相机使用方式 让他们能使用 iPhone 捕捉难忘时刻
在这个讲座中 我们将首先介绍什么是实体拍摄 以及支持哪些实体按钮 然后展示如何在 App 中 有效地使用这个 API 处理用户交互 并构建一个像我们在演示中 看到的那样 功能强大且响应迅速的相机界面
我们还将介绍 iOS 26 中的 一项令人期待的新功能 即通过 AirPods 进行远程相机控制
最后 我的同事 Nick 将 概括介绍 iPhone 16 上的 相机控制功能
在探索这个 API 的核心功能之前 让我们回顾一下在 iOS 中 打造出色相机体验 所涉及的关键框架 “相机”App 架构的核心是 AV Foundation 它通过用于拍照的 AVCapturePhotoOutput 和用于录像的 AVCaptureMovieFileOutput 等 API 提供底层拍摄功能
为了将 UI 层与 AV Foundation 结合起来 我们在这些框架之上使用了 AVKit
AVKit 包含一个特定于拍摄的 API 即 AVCaptureEventInteraction
现在让我们深入了解 AVCaptureEventInteraction 的 关键特性和功能 这个 API 允许覆盖 实体按钮的默认行为 例如调高音量和调低音量 或 iPhone 16 推出的相机控制
AVCaptureEventInteraction 支持的另一个按钮 是操作按钮 请查看我们去年的讲座 了解如何配置操作按钮以用于拍摄
每次按下实体按钮都会 触发一个拍摄事件通知 这个通知包含事件阶段 让你能够精确控制 整个按下动作的生命周期 有三个可能的阶段 began:按下按钮的那一刻 非常适合准备 App 的 camera 对象
cancelled:App 进入后台 或无法进行拍摄的时刻
ended:松开按钮的那一刻 在这个阶段 camera 对象应启动拍摄
AVCaptureEventInteraction 还支持区分在主要操作 和次要操作之间按下的按钮 按下按钮会触发仅发送给 指定处理程序的拍摄通知
主要操作由调低音量按钮、 操作按钮和相机控制触发 而次要操作由调高音量按钮触发 同一个按钮不能 同时触发两个处理程序 因为它们表示不同的操作 次要处理程序是可选的 如果没有指定 点按调高音量将触发主要操作 这种设计将模块化这一概念 引入了你的 App 让你在为用户设计 出色的相机体验时 拥有更大的灵活性 这个 API 专为 拍摄用例设计 系统仅向正在使用相机 的 App 发送拍摄事件 采用这个 API 会覆盖 实体按钮的默认行为 因此 App 必须始终正确响应 收到的任何事件 如果未能处理事件 将导致按钮无法正常工作 从而带来糟糕的用户体验
处于后台的拍摄 App 或当前并未运行 AVCaptureSession 的 App 不会收到任何事件 这时不管按下任何按钮 都将触发默认系统操作 例如调节音量或启动相机
尽管 AVCaptureEventInteraction 是专为 UIKit 设计的 API 但 SwiftUI 开发者也可以通过 onCameraCaptureEvent 视图修饰符 来获得它的功能 不管采用哪一种方式 都会产生相同的行为
现在我们已了解 AVCaptureEventInteraction 接下来让我们构建 一个简单的“相机”App 使用 SwiftUI 的 onCameraCaptureEvent 视图修饰符 来允许通过实体按钮拍摄照片 首先 让我们开始为 “相机”App 构建用户界面 我们将添加 CameraView 它负责在屏幕上显示相机输出
接下来我们在视图中添加 一个按钮 让用户能够拍照 我们将这个按钮连接到 CameraModel 以便轻点时触发拍照
现在我们有了功能正常的视图 当用户按下屏幕上的按钮时 可以拍照 然而 按下任何实体按钮 将触发系统操作 接下来我们使用本讲座中 讨论的 API 让按下这些实体按钮 成为特定于相机的操作 首先 我们导入 AVKit 框架 然后 我们将 onCameraCaptureEvent 视图修饰符附加到 CameraView 并指定在事件阶段 为 ended 时拍摄照片
就是这么简单! 只需另外添加 6 行代码 我们就实现了通过与内置 “相机”App 一样直观的 实体按钮互动来拍照 这就是利用 Capture Controls API 的强大之处 今年我们很高兴宣布 AVCaptureEventInteraction 还将支持通过点按 任意一侧的 AirPod 耳机柄 来触发主要操作 特别是 配备 H2 芯片的 AirPods 这将使用户无需与手机交互 即可远程拍下难忘的时刻
对于已采用这个 API 的开发者 这项功能将随 iOS 26 免费推出
现在 我们来看看 这项新功能的实际应用 我戴上右侧的 AirPod 再戴上左侧的 AirPod
很棒!
然后 为了配置 使用 AirPods 进行拍摄 让我们进入“设置”
并向下滚动到 “Remote Camera Capture”部分
在这里 我们可以选择 哪种类型的点按将触发拍摄 我将选择“按一下”选项
现在 返回“相机”App
我后退几步 然后通过点按其中一个 耳机柄来拍摄照片
太棒了 现在我不用触碰 设备就能控制相机
由于 AirPods 用于远程相机控制 因此音频反馈至关重要 因为用户在拍摄过程中 可能不会查看屏幕 但需要确认他们的命令已被识别
因此 我们推出了一个新 API 来控制声音播放 特别是点按 AirPod 耳机柄的声音 如果拍摄事件并非 由 AirPod 点按触发 AVCaptureEventInteraction 对象将不允许控制声音反馈
为了向 AVCaptureEventInteraction 用户提供这项新功能 而不要求他们完成任何额外的操作 我们为 AirPod 点按 添加了默认提示音
不过 这个声音可能不适合你的用例 因此你可以通过在 App 套装中 提供自定义声音来自定义声音播放
回到我们的“相机”App 具体来说 就是返回 .onCameraCaptureEvent 视图修饰符 在 iOS 26 中 如果我们保持这段代码不变 当用户点按 AirPods 耳机柄时 他们会听到默认声音 由于我们正在构建 一个专门用于拍照的 App 因此默认声音可能 并不适合我们的 App
为了针对特定场景 调整拍摄声音 我们首先使用 defaultSoundDisabled 参数 停用默认声音
如果需要音频反馈 我们可以使用 event 对象的 playSound 方法 播放 cameraShutter 声音 请注意 只有当拍摄操作 由点按 AirPods 耳机柄触发时 shouldPlaySound 属性才为 true
总之 AVCaptureEventInteraction API 显著简化了 为 App 构建高质量 相机体验的过程 我们介绍了这个 API 的 关键特性和实现方面的 最佳做法 包括今年的更新 即通过点按 AirPod 耳机柄 控制相机拍摄的功能 现在 有请 Nick 谈谈 AVCaptureControls 大家好 我叫 Nick Lupinetti 我是相机体验团队的软件工程师 很高兴为大家介绍 AVCaptureControl 这是一种将 iPhone 16 上的 相机控制转变为 实体硬件来控制相机 界面的有效方式 相机控制是一种多功能拍摄工具 可点击启动“相机”App、 充当快门按钮 和快速做出调整 而且操作时手指位置保持不变
我们来按顺序了解这三项功能 从启动开始 为了启动 App 相机控制需要在设备 锁定时也能访问 App 这意味着需要创建 锁定屏幕拍摄扩展 如需了解更多详细信息 请观看去年介绍 如何打造锁定屏幕 相机体验的讲座
其次 将相机控制用作 App 的快门按钮非常简单 只需设置 Vitaliy 之前 展示的其中一个 拍摄事件 API 即可完成! 相机控制运行的主要事件回调 与你为音量按钮 提供的主事件回调相同 接下来是我最喜欢的功能 调整相机设置 与传统相机快门一样 相机控制支持轻按手势 这样可以激活 干净的预览以专注于构图 并通过滑动控件 来呈现要调整的设置 通过轻按两下 然后滑动相机控制 并再次轻按进行确认 可以选择其他设置
概括来讲 有两种类型的控件: 用于数值的滑块 和用于列表项目的选择器
滑块又分为两种类型: 连续滑块和离散滑块
连续滑块可以选择 指定范围内的任何数值 例如 iOS 自带了 一个连续缩放滑块 它支持设备可以操作的 推荐下限和 上限范围内的 所有缩放系数 离散滑块也选择数值 可以从你提供的显式集合中选择 也可以按从一个值到 另一个值的固定步长来选择 iOS 提供了一个内建的 离散滑块来驱动曝光偏差 增量为三分之一 并介于正负二之间 这是传统摄影中易于管理的单位
选择器与离散滑块类似 支持有限的选择 但它们带有索引 每个索引都映射到控件的 一个命名状态 例如闪光灯的“开”和“关” 或“相机”App 中的摄影风格名称 好的 现在我们已了解 各种类型的控件 接下来让我们来看看实现它们的 控件在 AV Foundation 框架中定义 AVCaptureControl 是 其他类会继承的抽象基类
有两个系统定义的子类 它们允许任何 App 采用与内建“相机”App 相同的缩放或曝光偏差行为 最后 还有两个通用子类 分别用于滑块 包括连续滑块和离散滑块 以及选择器 你可以自行定义它们的行为 要在 App 中采用控件 你需要将它们 添加到 AVCaptureSession 中 通常 配置会话的第一步 是创建拍摄设备 并封装为输入 以添加到会话中 接下来 创建所有系统定义的控件 并引用同一个设备 以便它们代表你自己驱动设备属性 同时 还要创建所有具有 App 定义的行为的控件 最后将每个控件添加到会话中
为了让你的 App 在用户与相机控制交互时 做出响应 需要考虑几个流程 系统提供的控件会将相机控制的值 直接应用于配置的设备 你无需自行设置 videoZoomFactor 或 exposureTargetBias
但是 你可能需要更新模型或 UI 如果你已在使用键值观察 即 KVO 来监听 相关属性的变化 那么可以继续使用 这一机制来更新界面
如果你没有使用 KVO 请为系统控件创建操作处理程序 当值变化时 这个处理程序 会被主线程调用 以便直接更新 UI
始终为 App 定义的控件 创建在指定队列上 运行的操作回调 如果你的控件需要驱动拍摄设置 你可以通过指定 用于管理这一状态的 队列来同步实现 然后 你可以在主队列上更新 UI
太好了 现在我们已准备就绪 可以在我和 Vitaliy 正在 开发的 App 中采用相机控制了 由于他已经添加了拍摄交互 因此控件已可以 作为快门按钮来拍照 而无需额外编写任何代码
但是我还想支持使用 相机控制进行缩放 因此我们接下来添加这个功能
我们当前正在配置 拍摄会话以使用设备 首先 我们将检查控件是否受支持 因为它们适用于 具有相机控制的设备 例如 iPhone 16
系统提供的控件非常容易创建 只需一行代码即可
在添加控件之前 请确保它能被会话接受 例如不能为已经与缩放控件 关联的设备添加 系统提供的缩放控件 最后 我们将控件添加到会话中
就是这样 我们在 App 中完美 实现了使用相机控制进行缩放! 但是 有一个问题 我还支持使用捏合手势来放大 在使用相机控制放大后 UI 没有及时更新 因此捏合手势会回到旧的缩放系数 但是 这很容易解决 我们只需为滑块创建一个操作闭包 它接收缩放系数作为参数 新值将通过委托回调 或可观察模型属性应用于 UI
一旦捏合手势背后的模型 与相机控制的缩放系统同步 我便可以使用相机控制进行缩放 并且捏合手势总是 从正确的缩放系数开始
现在 我想添加一个 并非现成可用的控件 但是 在我们自行创建控件之前 让我们思考一下出色的 控件必须满足什么条件 顾名思义 相机控制是 与 iPhone 相机配合使用的 因此它应该影响拍摄的外观或体验 如果控件影响 App 中不相关的 方面 则会让用户感到困惑 绝对不要仅仅为了采用 相机控制而引入拍摄会话 因为相机的运行 对电量和隐私有要求 最好保留用于拍摄体验 自定义控件的一个 绝佳示例是选择器 它会遍历 App 支持的效果或滤镜
这类控件通常需要更靠近 拍摄端而不是 UI 端来运行 下面我们来看看具体实现方式 从我们刚才编写的代码着手 我们将使缩放控件 成为众多控件之一 请注意 可以添加的控件 存在数量限制 会话的 maxControlsCount 属性会报告这一限制的情况 一旦达到限制 canAddControl 将返回 false 现在 我们可以定义效果 你的效果可能在专用队列上 使用视频样本缓冲区 进行渲染 但对于我们的 App 我将使用 iOS 17 推出的 reaction 效果 在这里 我们已经基于 可用的无序效果集 构建了有序的效果及其名称列表 选择器将使用 这些效果名称进行初始化 以便在遍历选项时显示 选择器还需要有 一个自己的名称以及 一个 SF Symbol 图像 以便与缩放控件区分开来 如果控件当前不受支持 最好将其禁用 而不是忽略 这样 它仍然可见 只是不可交互 否则 系统会选择 另一个控件作为备用控件 这可能会导致用户感到困惑
当用户更改选择器的选定索引时 我们将执行相应的 reaction 我们将会话队列作为操作的目标 因为这是我们用于设备管理 的隔离上下文 余下的工作就是将选择器 添加到控件数组中 我们来看看效果如何!
当我与相机控制交互时 请注意在这项新配置中 缩放被停用 让我们更改控件 我将在叠层上轻扫 现在我可以 查看列表中的选择器了 我将滚动到它并 轻按以显示相关选项 现在我可以依次选择每个效果 并观看它们在预览中播放
太棒了!
学完 Vitaliy 和我 在本次讲座中所讲的内容 你便拥有了大量出色的工具 来构建一流的“相机”App
我们已了解如何在 iOS 设备上 使用实体按钮来拍摄媒体 包括在 iOS 26 中与 AirPods 交互有多么轻松 我们还学习了如何利用 相机控制作为便捷工具 来增强 App 的拍摄交互 在 developer.apple.com/cn 上 还有更多出色的资源 包括有关相机控制的 《人机界面指南》、 有关设置 AirPods 来测试新功能的指南 以及用于进一步了解 如何采用相机控制 的文章和示例代码 我迫不及待 想要看到你们构建出 引人注目的“相机”App 谢谢观看!
-
-
5:35 - Initial PhotoCapture view setup
import SwiftUI struct PhotoCapture: View { var body: some View { VStack { CameraView() } } }
-
5:37 - Connecting a button to the camera model
import SwiftUI struct PhotoCapture: View { let camera = CameraModel() var body: some View { VStack { CameraView() Button(action: camera.capturePhoto) { Text("Take a photo") } } } }
-
6:10 - Importing AVKit
import AVKit import SwiftUI struct PhotoCapture: View { let camera = CameraModel() var body: some View { VStack { CameraView() Button(action: camera.capturePhoto) { Text("Take a photo") } } } }
-
6:14 - Setting up onCameraCaptureEvent view modifier
import AVKit import SwiftUI struct PhotoCapture: View { let camera = CameraModel() var body: some View { VStack { CameraView() .onCameraCaptureEvent { event in if event.phase == .ended { camera.capturePhoto() } } Button(action: camera.capturePhoto) { Text("Take a photo") } } } }
-
8:53 - Default sound for onCameraCaptureEvent view modifier
.onCameraCaptureEvent { event if event.phase == .ended { camera.capturePhoto() } }
-
9:13 - Play photo shutter sound on AirPod stem click
.onCameraCaptureEvent(defaultSoundDisabled: true) { event in if event.phase == .ended {a if event.shouldPlaySound {d event.play(.cameraShutter) } } camera.capturePhoto() }
-
14:46 - Add a build-in zoom slider to Camera Control
captureSession.beginConfiguration() // configure device inputs and outputs if captureSession.supportsControls { let zoomControl = AVCaptureSystemZoomSlider(device: device) if captureSession.canAddControl(zoomControl) { captureSession.addControl(zoomControl) } } captureSession.commitConfiguration()
-
15:40 - Modifying the built-in zoom slider to receive updates when zoom changes
let zoomControl = AVCaptureSystemZoomSlider(device: device) { [weak self] zoomFactor in self?.updateUI(zoomFactor: zoomFactor) }
-
16:46 - Adding a custom reaction-effects picker alongside zoom slider
let reactions = device.availableReactionTypes.sorted { $0.rawValue < $1.rawValue } let titles = reactions.map { localizedTitle(reaction: $0) } let picker = AVCaptureIndexPicker(“Reactions", symbolName: “face.smiling.inverted”, localizedIndexTitles: titles) picker.isEnabled = device.canPerformReactionEffects picker.setActionQueue(sessionQueue) { index in device.performEffect(for: reactions[index]) } let controls: [AVCaptureControl] = [zoomControl, picker] for control in controls { if captureSession.canAddControl(control) { captureSession.addControl(control) } }
-
-
- 0:00 - 简介
了解如何使用 AVKit 和 AVFoundation 来改善相机 App 中的用户交互。现在,你可以通过编程方式将实体按钮手势 (例如音量“增大”和“减小”) 映射到相机操作上,使用户能够使用手机的按钮来拍照和开始视频录制。 iOS 26 的一项新功能是 AirPods 远程相机控制。了解支持的实体按钮、如何使用 AVCaptureEventInteraction API,以及 iPhone 16 的相机控制概述。
- 2:51 - 实体拍摄
AVCaptureEventInteraction 支持操作按钮;如需了解配置详细信息,可以观看去年的讲座“将 App 控制扩展到系统级别”。
- 3:01 - 事件处理
AVCaptureEventInteraction 是一个 API,用于在相机 App 中控制实体按钮按压操作的生命周期。它提供了三个事件阶段:“began”(开始)、“cancelled”(已取消) 和“ended”(已结束)。“ended”阶段是 camera 对象应启动拍摄的时刻。 这个 API 区分主要操作和次要操作,分别由特定按钮触发 (主要操作:调低音量按钮、操作按钮、相机控制按钮;次要操作:调高音量按钮)。这种设计为 App 设计带来了模块化和灵活性。 SwiftUI 开发者可以通过 onCameraCaptureEvent 视图修饰符访问这项功能。通过导入 AVKit 框架并将这个修饰符附加到 CameraView,只需几行代码,即可启用实体按钮拍照功能,模仿内置“相机”App 的行为。
- 6:39 - AirPods 远程拍摄
从 iOS 26 开始,搭载 H2 芯片的 AirPods 将支持通过点按耳机柄来实现远程相机控制。用户可以在“设置”App 中配置这项功能,并选取通过哪个耳机柄点按操作来触发拍照。 Apple 推出了一个新的 API 来为这些耳机柄点按操作提供音频反馈,并包含默认提示音,但也可针对特定 App 自定这个声音。这个增强功能让用户能够解放双手捕捉精彩瞬间,并通过音频提示确保操作确认。
- 10:00 - 详细控制
AVCaptureControl 是 iPhone 16 中的一项新功能,支持为相机界面创建物理硬件控制。它能让用户快速启动相机 App 并调整相机设置,还可充当快门按钮。 这个控件支持两种主要调整类型:用于数值的滑块 (连续和离散),以及用于列表中项目的选择器。这些控件在 AVFoundation 框架中定义。 你可以添加系统定义的缩放或曝光偏差控件,也能创建具有 App 定义行为的控件。将这些控件添加到 AVCaptureSession 后,App 可通过操作处理程序或键值观察 (KVO) 来响应交互,并相应地更新 UI。 要增强相机 App 的功能,请利用相机控制轻松添加系统提供的控制,例如变焦,而这只需一行代码。但务必要确保会话接受这个控件,并使 UI 与控件状态同步,避免出现缩放系数过时等问题。 创建自定控件时需注意,相机控制专为拍摄场景设计。自定控件的一个典型示例是选择器,它让用户能够选择效果或滤镜。这类控件需要比 UI 更贴近拍摄会话来运行。 你可以定义效果,使用效果名称初始化选择器,并在不支持时停用控件。通过将会话队列设置为操作目标,可以确保对设备进行正确的隔离和管理。 借助拍摄控制,你可以打造吸引用户关注的出色相机 App。