Xcode开发如何实现iPhone相机仅在指定ViewController运行、其他页面关闭
解决方案
方案1:相机跟随所属ViewController生命周期运行(最推荐)
这是最低耦合、最合理的实现方式,不需要跨ViewController操作相机,只需要在相机所属的ViewController的生命周期方法中管理AVCaptureSession的启停即可:
- 第一步:在相机ViewController中全局持有
AVCaptureSession实例和专属相机操作串行队列
class CameraViewController: UIViewController { var captureSession: AVCaptureSession? // 相机操作专属队列,避免阻塞主线程 let captureQueue = DispatchQueue(label: "com.yourapp.cameraQueue", attributes: [], autoreleaseFrequency: .workItem) }
- 第二步:在ViewController即将离开视图时停止相机
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) captureQueue.async { [weak self] in guard let self = self, let session = self.captureSession, session.isRunning else { return } session.stopRunning() // 不需要保留相机实例的话可以直接释放 // self.captureSession = nil } }
- 第三步:如果需要切回该页面时相机自动恢复运行,补充
viewWillAppear逻辑
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) guard let session = captureSession, !session.isRunning else { return } captureQueue.async { session.startRunning() } }
方案2:跨ViewController关闭相机
如果业务场景确实需要在其他页面主动关闭相机,可通过通知实现解耦操作:
- 第一步:在相机ViewController中添加通知观察者
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(stopCameraSession), name: NSNotification.Name("kNotificationStopCamera"), object: nil) } @objc private func stopCameraSession() { captureQueue.async { [weak self] in self?.captureSession?.stopRunning() self?.captureSession = nil } }
- 第二步:需要关闭相机的位置发送通知即可
NotificationCenter.default.post(name: NSNotification.Name("kNotificationStopCamera"), object: nil)
注意事项
AVCaptureSession的startRunning和stopRunning都是同步阻塞操作,必须放在子队列执行,禁止在主线程调用,否则会导致UI卡顿- 所有闭包中使用
[weak self]修饰,避免循环引用导致ViewController无法释放,相机资源被持续持有 - 如果相机逻辑封装在独立的管理类中,也可以给管理类添加全局启停方法,但更推荐跟随ViewController生命周期管理的方案,资源占用更低
内容的提问来源于stack exchange,提问作者Rogério
相关产品推荐
相关产品推荐

