You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中打开全屏设置视图时停止相机运行的优雅解决方案

Fix: Camera Keeps Running When Presenting Settings View in SwiftUI

Hey there! I see the issue you're facing—when you present the settings view via fullScreenCover, the camera stays active (that green privacy indicator doesn't go away) because the underlying AVCaptureSession in your CustomCameraController never stops running. Let's fix this with a straightforward, maintainable solution.

Why This Happens

The CameraPreviewRepresentable (and its attached CustomCameraController) isn't destroyed when you present the settings view—it's just hidden beneath the full-screen cover. Since the captureSession was started in viewDidLoad, it continues running in the background, keeping the camera active.

Step-by-Step Solution

1. Add Session Control Methods to CustomCameraController

First, let's give our camera controller explicit methods to stop and restart the capture session. We'll also make sure these operations run on the main thread (required for AVFoundation interactions):

import UIKit
import Combine
import AVFoundation

class CustomCameraController: UIViewController {
    // ... (keep your existing properties and methods)
    
    func stopRunningCaptureSession() {
        DispatchQueue.main.async {
            if self.captureSession.isRunning {
                self.captureSession.stopRunning()
            }
        }
    }
    
    func restartCaptureSession() {
        DispatchQueue.main.async {
            if !self.captureSession.isRunning {
                self.captureSession.startRunning()
            }
        }
    }
    
    // ... (keep your existing setup methods)
}

2. Listen to Settings View Presentation State

In your CameraView, we'll listen for changes to the didTapSettings binding. When the settings view is presented, we'll stop the camera session; when it's dismissed, we'll restart it:

struct CameraView: View {
    @State private var didTapCapture = false
    @State private var didTapSettings = false
    let cameraController: CustomCameraController
    @ObservedObject var cameraViewModel: CameraViewModel
    
    var body: some View {
        VStack {
            // ... (keep your existing camera preview and button layout)
        }
        .fullScreenCover(isPresented: $didTapSettings) {
            VStack(spacing: 30) {
                Text("Settings View ⚙️")
                    .font(.largeTitle)
                Button("OK") {
                    didTapSettings.toggle()
                }
            }
        }
        .onChange(of: didTapSettings) { isSettingsPresented in
            if isSettingsPresented {
                // Stop camera when settings view appears
                cameraController.stopRunningCaptureSession()
            } else {
                // Restart camera when settings view is dismissed
                cameraController.restartCaptureSession()
            }
        }
    }
}

3. Optional: Add Safety Checks (For Robustness)

If you want to make sure the session can safely restart (e.g., if the user revoked camera permissions while in settings), you can add a check in restartCaptureSession:

func restartCaptureSession() {
    DispatchQueue.main.async {
        guard AVCaptureDevice.authorizationStatus(for: .video) == .authorized else {
            // Handle permission denial here (e.g., show alert to guide user to settings)
            return
        }
        if !self.captureSession.isRunning {
            self.captureSession.startRunning()
        }
    }
}

How This Works

  • When didTapSettings becomes true (settings view is presented), we call stopRunningCaptureSession()—this halts the camera session, turning off the green privacy indicator immediately.
  • When didTapSettings becomes false (settings view is dismissed), we call restartCaptureSession()—this resumes the camera session so the user can take photos again without any extra steps.

This approach keeps camera logic encapsulated where it belongs (in CustomCameraController) and uses SwiftUI's native state observation to trigger actions at the right moments—clean, maintainable, and user-friendly.

内容的提问来源于stack exchange,提问作者ViOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 22:53:15