Swift 4:二维码扫描成功后及点击确认按钮时关闭扫描器
解决QR扫描后无法关闭相机的问题
嗨,我看到你遇到的问题了——扫描成功后没法关闭相机,核心原因是你把AVCaptureSession定义成了scanButtonTapped方法里的局部变量,方法执行完这个session就被系统释放了,后续点击确认按钮时根本找不到它来停止相机运行。
下面是具体的修复方案,一步步来:
第一步:把AVCaptureSession改成类的属性
在你的ViewController类里,先声明一个全局的session变量,这样整个类的方法都能访问到它:
class YourViewController: UIViewController { // 声明全局的捕获会话 private var captureSession: AVCaptureSession? // 如果你用了预览层,也可以在这里声明 private var previewLayer: AVCaptureVideoPreviewLayer? // 其他代码... }
第二步:修改scanButtonTapped方法,使用全局session
把原来方法里的局部session替换成我们刚声明的全局属性:
@objc func scanButtonTapped(sender: UIButton) { captureSession = AVCaptureSession() guard let captureDevice = AVCaptureDevice.default(for: .video) else { self.view.makeToast("无法获取摄像头权限") return } do { let input = try AVCaptureDeviceInput(device: captureDevice) guard let session = captureSession else { return } if session.canAddInput(input) { session.addInput(input) } // 这里添加QR码识别的输出(如果之前没加的话) let output = AVCaptureMetadataOutput() if session.canAddOutput(output) { session.addOutput(output) output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) output.metadataObjectTypes = [.qr] } // 添加预览层到界面(显示相机画面) previewLayer = AVCaptureVideoPreviewLayer(session: session) previewLayer?.frame = self.view.bounds previewLayer?.videoGravity = .resizeAspectFill self.view.layer.insertSublayer(previewLayer!, at: 0) // 启动会话,开始扫描 session.startRunning() } catch { self.view.makeToast("抱歉,扫描初始化失败") captureSession = nil previewLayer?.removeFromSuperlayer() previewLayer = nil } }
第三步:实现确认按钮的点击方法,关闭相机
写一个确认按钮的响应方法,在里面停止session,并且清理界面资源:
@objc func confirmButtonTapped(sender: UIButton) { // 停止捕获会话,关闭相机 captureSession?.stopRunning() // 移除预览层,恢复界面 previewLayer?.removeFromSuperlayer() // 置空变量,释放资源 captureSession = nil previewLayer = nil }
额外注意点
- 别忘了给你的确认按钮绑定这个
confirmButtonTapped方法 - 如果项目里有摄像头权限申请逻辑,要确保用户已经授权,否则相机无法正常启动
这样修改后,点击确认按钮就能正常关闭相机啦~
内容的提问来源于stack exchange,提问作者Yana Shetty
相关产品推荐
相关产品推荐

