无法检测QR码

时间:2017-04-13 08:02:26

标签: xcode swift3 ios10

我试图让应用程序在ios 10和Swift 3中扫描QR码。但是,我的QRScannerController无法检测到QR码但显示了摄像头视图。

我不明白代码有什么问题。这是控制器的实现:

import UIKit
import AVFoundation

class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate  {

    @IBOutlet var messageLabel:UILabel!
    @IBOutlet var topbar: UIView!
    //TESTING
    var captureSession: AVCaptureSession?
    var videoPreviewLayer: AVCaptureVideoPreviewLayer?
    var qrCodeFrameView: UIView?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter
        let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

        do {

            view.bringSubview(toFront: messageLabel)
            view.bringSubview(toFront: topbar)

            // Get an instance of the AVCaptureDeviceInput class using the previous deivce object
            let input = try AVCaptureDeviceInput(device: captureDevice)

            // Initialize the captureSession object
            captureSession = AVCaptureSession()

            // Set the input devcie on the capture session
            captureSession?.addInput(input)

            // Initialize a AVCaptureMetadataOutput object and set it as the input device 
            let captureMetadataOutput = AVCaptureMetadataOutput()
            captureSession?.addOutput(captureMetadataOutput)

            // Set delegate and use the default dispatch queue to execute the call back
            captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

            //Initialise the video preview layer and add it as a sublayer to the viewPreview view's layer
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            videoPreviewLayer?.frame = view.layer.bounds
            view.layer.addSublayer(videoPreviewLayer!)

            //start video capture
            captureSession?.startRunning()

            //Initialize QR Code Frame to highlight the QR code
            qrCodeFrameView = UIView()

            if let qrCodeFrameView = qrCodeFrameView {
                qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
                qrCodeFrameView.layer.borderWidth = 2
                view.addSubview(qrCodeFrameView)
                view.bringSubview(toFront: qrCodeFrameView)
            }

            func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {

                // Check if the metadataObjects array is not nil and it contains at least one object.
                if metadataObjects == nil || metadataObjects.count == 0 {
                    qrCodeFrameView?.frame = CGRect.zero
                    messageLabel.text = "No QR code is detected"
                    return
                }

                // Get the metadata object.
                let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

                if metadataObj.type == AVMetadataObjectTypeQRCode {
                    // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
                    let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
                    qrCodeFrameView?.frame = barCodeObject!.bounds

                    if metadataObj.stringValue != nil {
                        messageLabel.text = metadataObj.stringValue
                    }
                }
            }

        } catch {
            //If any error occurs, simply print it out
            print(error)
            return
        }


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

1 个答案:

答案 0 :(得分:1)

您的消息标签位于视图控制器视图下方。只需将消息标签放在视图末尾的前面,确实加载会有所帮助。

我创建了一个示例项目,它在iPhone上运行良好。请查看here