2025 Photos & Camera
WWDC25 · 19 min · Photos & Camera
Enhancing your camera experience with capture controls
Learn how to customize capture controls in your camera experiences. We’ll show you how to take photos with all physical capture controls, including new AirPods support, and how to adjust settings with Camera Control.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 9 snippets
Initial PhotoCapture view setup
import SwiftUI
struct PhotoCapture: View {
var body: some View {
VStack {
CameraView()
}
}
} 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")
}
}
}
} 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")
}
}
}
} 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")
}
}
}
} Default sound for onCameraCaptureEvent view modifier
.onCameraCaptureEvent { event
if event.phase == .ended {
camera.capturePhoto()
}
} 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()
} 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() 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)
} 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)
}
} Resources
- Creating a camera experience for the Lock Screen
- Forum: Photos & Camera
- Supporting Continuity Camera in your tvOS app
- DockKit
- Creating a camera extension with Core Media I/O
- Accessing the camera while multitasking
- Supporting Continuity Camera in your macOS app
- Scanning data with the camera
- AVMultiCamPiP: Capturing from Multiple Cameras
- Capturing photos with depth
- AVFoundation
- Capture setup
Related sessions
-
23 min -
29 min -
33 min