Add Center Stage support alongside MijickCamera

Center Stage is a device-level Apple feature that works independently
of any camera framework. Added:

- Center Stage button in top control bar (person.crop.rectangle icon)
- checkCenterStageAvailability() checks device.activeFormat.isCenterStageSupported
- toggleCenterStage() uses AVCaptureDevice.isCenterStageEnabled
- Button only appears on devices that support Center Stage
- Yellow highlight when enabled

Works with MijickCamera since Center Stage is controlled at the
AVCaptureDevice level, not the camera view level.
This commit is contained in:
Matt Bruce 2026-01-02 16:19:46 -06:00
parent 489318b220
commit b97590f1c1

View File

@ -2,6 +2,7 @@ import SwiftUI
import MijickCamera
import Bedrock
import Photos
import AVFoundation
struct ContentView: View {
@State private var settings = SettingsViewModel()
@ -15,6 +16,10 @@ struct ContentView: View {
@State private var capturedVideoURL: URL?
@State private var showPostCapturePreview = false
// Center Stage support
@State private var isCenterStageAvailable = false
@State private var isCenterStageEnabled = false
var body: some View {
GeometryReader { geometry in
let maxRingSize = calculateMaxRingSize(for: geometry)
@ -65,6 +70,9 @@ struct ContentView: View {
}
}
.ignoresSafeArea()
.onAppear {
checkCenterStageAvailability()
}
.sheet(isPresented: $showPaywall) {
ProPaywallView()
}
@ -86,6 +94,22 @@ struct ContentView: View {
private var topControlBar: some View {
HStack {
// Center Stage button (only shown when available)
if isCenterStageAvailable {
Button {
toggleCenterStage()
} label: {
Image(systemName: isCenterStageEnabled ? "person.crop.rectangle.fill" : "person.crop.rectangle")
.font(.body)
.foregroundStyle(isCenterStageEnabled ? .yellow : .white)
.padding(Design.Spacing.small)
.background(.ultraThinMaterial, in: Circle())
}
.accessibilityLabel(String(localized: "Center Stage"))
.accessibilityValue(isCenterStageEnabled ? "On" : "Off")
.accessibilityHint(String(localized: "Keeps you centered in frame"))
}
Spacer()
// Grid toggle
@ -115,6 +139,28 @@ struct ContentView: View {
}
}
// MARK: - Center Stage
/// Checks if Center Stage is available on this device
private func checkCenterStageAvailability() {
// Center Stage requires a compatible device (iPad with A12+ or some iPhones)
guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) else {
isCenterStageAvailable = false
return
}
// Check if the device supports Center Stage
isCenterStageAvailable = device.activeFormat.isCenterStageSupported
isCenterStageEnabled = AVCaptureDevice.isCenterStageEnabled
}
/// Toggles Center Stage on/off
private func toggleCenterStage() {
AVCaptureDevice.centerStageControlMode = .app
AVCaptureDevice.isCenterStageEnabled.toggle()
isCenterStageEnabled = AVCaptureDevice.isCenterStageEnabled
}
// MARK: - Post Capture View
@ViewBuilder