Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

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 ↗

Transcript all transcripts

Chapters

Code shown on screen · 9 snippets

Initial PhotoCapture view setup swift · at 5:35 ↗
import SwiftUI

struct PhotoCapture: View {
    var body: some View {
        VStack {
            CameraView()
        }
    }
}
Connecting a button to the camera model swift · at 5:37 ↗
import SwiftUI

struct PhotoCapture: View {
    let camera = CameraModel()
    var body: some View {
        VStack {
            CameraView()
            Button(action: camera.capturePhoto) {
                Text("Take a photo")
            }
        }
    }
}
Importing AVKit swift · at 6:10 ↗
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 swift · at 6:14 ↗
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 swift · at 8:53 ↗
.onCameraCaptureEvent { event
	if event.phase == .ended {
   	camera.capturePhoto() 
  }
}
Play photo shutter sound on AirPod stem click swift · at 9:13 ↗
.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 swift · at 14:46 ↗
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 swift · at 15:40 ↗
let zoomControl = AVCaptureSystemZoomSlider(device: device) { [weak self] zoomFactor in
    self?.updateUI(zoomFactor: zoomFactor)
}
Adding a custom reaction-effects picker alongside zoom slider swift · at 16:46 ↗
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