iOS 26/27 introduces new AVCapture APIs for the square-sensor Center Stage front camera on iPhone 17, iPhone Air, and iPhone 17 Pro ā including dynamic aspect ratio switching, an AVCaptureSmartFramingMonitor for automatic face-aware zoom and rotation, and low-latency video stabilization.
⢠The new square 95° ultra-wide front sensor enables portrait or landscape selfies without rotating the phone ā your app must adopt dynamicAspectRatio to unlock this flexibility.
⢠AVCaptureSmartFramingMonitor delivers automatic zoom-and-rotate recommendations based on face/gaze detection so group shots are always well-framed without user intervention.
⢠Low-latency stabilization mode on AVCaptureConnection dramatically reduces shake in video calls, and Center Stage can now be enabled programmatically (not just from Control Center) for non-VoIP apps.
Demonstrates selecting the Center Stage front camera, picking a format that supports dynamic aspect ratio, enabling the AVCaptureSmartFramingMonitor, and applying its framing recommendations live to keep group selfies perfectly framed.
import AVFoundation
import SwiftUI
@MainActor
final class CenterStageCameraModel: NSObject, ObservableObject {
let session = AVCaptureSession()
private var device: AVCaptureDevice?
private var smartFramingObservation: NSKeyValueObservation?
func configure() {
session.beginConfiguration()
defer { session.commitConfiguration() }
// Find the Center Stage front camera (square ultra-wide sensor)
let discovery = AVCaptureDevice.DiscoverySession(
deviceTypes: [.builtInUltraWideCamera],
mediaType: .video,
position: .front
)
guard let cam = discovery.devices.first else { return }
self.device = cam
guard let input = try? AVCaptureDeviceInput(device: cam) else { return }
if session.canAddInput(input) { session.addInput(input) }
let photoOutput = AVCapturePhotoOutput()
if session.canAddOutput(photoOutput) { session.addOutput(photoOutput) }
// Find a format supporting dynamic aspect ratio (4032 photo format)
let targetRatios: [AVCaptureDevice.DynamicAspectRatio] = [.ratio4x3, .ratio3x4]
guard let bestFormat = cam.formats.first(where: { format in
let supported = format.supportedDynamicAspectRatios
return targetRatios.allSatisfy { supported.contains($0) }
}) else { return }
try? cam.lockForConfiguration()
cam.activeFormat = bestFormat
// Start in 4x3 landscape orientation
cam.dynamicAspectRatio = .ratio4x3
// Enable the smart framing monitor for auto zoom + rotate
let monitor = cam.smartFramingMonitor
monitor.enabledFramings = monitor.supportedFramings
cam.unlockForConfiguration()
// Observe framing recommendations and apply them
smartFramingObservation = monitor.observe(
\.recommendedFraming,
options: [.new]
) { [weak self] mon, _ in
guard let recommendation = mon.recommendedFraming else { return }
Task { @MainActor in
self?.applyRecommendation(recommendation)
}
}
monitor.startMonitoring()
}
private func applyRecommendation(
_ framing: AVCaptureSmartFramingMonitor.Framing
) {
guard let cam = device else { return }
try? cam.lockForConfiguration()
// Apply aspect ratio first, then zoom for smooth transition
cam.dynamicAspectRatio = framing.aspectRatio
cam.videoZoomFactor = framing.zoomFactor
cam.unlockForConfiguration()
}
func tapToRotate() {
guard let cam = device else { return }
try? cam.lockForConfiguration()
// Toggle between landscape and portrait
cam.dynamicAspectRatio = (cam.dynamicAspectRatio == .ratio4x3) ? .ratio3x4 : .ratio4x3
cam.unlockForConfiguration()
}
}
struct CenterStageCameraView: View {
@StateObject private var model = CenterStageCameraModel()
var body: some View {
ZStack(alignment: .bottom) {
CameraPreview(session: model.session)
.ignoresSafeArea()
Button("Tap to Rotate") {
model.tapToRotate()
}
.buttonStyle(.borderedProminent)
.padding()
}
.task { model.configure() }
}
}
struct CameraPreview: UIViewRepresentable {
let session: AVCaptureSession
func makeUIView(context: Context) -> UIView {
let view = UIView()
let layer = AVCaptureVideoPreviewLayer(session: session)
layer.videoGravity = .resizeAspectFill
layer.frame = UIScreen.main.bounds
view.layer.addSublayer(layer)
Task.detached { self.session.startRunning() }
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}⢠Changing dynamicAspectRatio during AVCaptureMovieFileOutput recording automatically stops the recording ā handle the completion timestamp carefully. ⢠Sensor orientation compensation is on by default and physically rotates HEIC/JPEG photos; RAW and Apple ProRAW captures are never compensated. ⢠Smart framing recommendations are only issued when the 4032 photo format is active. ⢠Center Stage enabled state is per-process and applies to all supported cameras in your app once set.
Requires iPhone 17, iPhone Air, or iPhone 17 Pro. dynamicAspectRatio and AVCaptureSmartFramingMonitor only work with the front-facing .builtInUltraWideCamera on the square 4032 or 1280ā2160 formats. Center Stage programmatic control requires the same device lineup.
More iOS 27 APIs land every week.
Get notified when new capabilities are published ā no noise, just signal.