简体   繁体   English

iOS如何在成功扫描QR码Swift 4后关闭相机

[英]iOS How to close camera after successfully scanning QR code Swift 4

How I can close camera after successfully scanning QR code? 成功扫描二维码后如何关闭相机? My problem is when I scan code from QR, camera is not closed after scanning. 我的问题是当我从QR扫描代码时,扫描后相机未关闭。 How I can close camera? 我怎么能关闭相机? My code: 我的代码:

var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
var qrCode = String()

func failed() {
        let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default))
        present(ac, animated: true)
        captureSession = nil
    }

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        captureSession.stopRunning()

        if let metadataObject = metadataObjects.first {
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
            guard let stringValue = readableObject.stringValue else { return }
            AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            found(code: stringValue)
        }

        dismiss(animated: true)

    }

    func found(code: String) {
        print(code)
        qrCode = code
    }

    override var prefersStatusBarHidden: Bool {
        return true
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }

Button which open camera: 打开相机的按钮:

 @IBAction func scanQrButton(_ sender: Any) {
    view.backgroundColor = UIColor.black
    captureSession = AVCaptureSession()

    guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
    let videoInput: AVCaptureDeviceInput

    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
    } catch {
        return
    }

    if (captureSession.canAddInput(videoInput)) {
        captureSession.addInput(videoInput)
    } else {
        failed()
        return
    }

    let metadataOutput = AVCaptureMetadataOutput()

    if (captureSession.canAddOutput(metadataOutput)) {
        captureSession.addOutput(metadataOutput)

        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [.qr]
    } else {
        failed()
        return
    }

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = view.layer.bounds
    previewLayer.videoGravity = .resizeAspectFill
    view.layer.addSublayer(previewLayer)

    captureSession.startRunning()
}

As you can see, I have code which opens the camera and scan QR, but I want to close camera after the code is scanned without segue. 正如您所看到的,我有打开相机并扫描QR的代码,但是我希望在没有segue的情况下扫描代码后关闭相机。

你试过这个吗?

self.captureSession?.stopRunning()

You can use the instance method stopRunning() on your session after you perform the scan to stop the capture : 执行扫描以停止捕获后,可以在会话中使用实例方法stopRunning():

captureSession.stopRunning()

And then dismiss the view with the preview of the camera output (here removeFromSuperlayer() will work I think). 然后使用相机输出的预览关闭视图(这里我认为removeFromSuperlayer()将起作用)。 You can use the following method to detect when a QR code was scanned after provided by the AVCaptureMetadataOutputObjectsDelegate: 您可以使用以下方法检测AVCaptureMetadataOutputObjectsDelegate提供的QR码扫描时间:

optional func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

You should also put startRunning() on a serial queue as stated by Apple documentation : 您还应该按照Apple文档中的说明将startRunning()放在串行队列上:

The startRunning() method is a blocking call which can take some time, therefore you should perform session setup on a serial queue so that the main queue isn't blocked (which keeps the UI responsive). startRunning()方法是一个阻塞调用,可能需要一些时间,因此您应该在串行队列上执行会话设置,以便不阻止主队列(这使UI保持响应)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM