ios - 如何在按下按钮时扫描二维码?

标签 ios swift qr-code camera-view

我正在使用 https://www.hackingwithswift.com/example-code/media/how-to-scan-a-qr-code 提供的代码制作我自己的扫描应用程序。但我喜欢在按下按钮时进行扫描。现在为此,我将教程中的 viewDidLoad() 部分放入其自己的函数中:

func cameraScanningLayer(){
    view.backgroundColor = UIColor.blackColor()
    captureSession = AVCaptureSession()

    let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    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: dispatch_get_main_queue())
        // need to scan barcode + QRcode
        metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeCode39Code]
    } else {
        failed()
        return
    }

    // Previewlayer with camera
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
    previewLayer.frame = viewForLayer.bounds;
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    viewForLayer.layer.addSublayer(previewLayer);

    captureSession.startRunning();
}

按钮操作调用该函数:

func buttonScanAction() {
    print("Scan")
    scanEnabled = true // like to use some kind of bool/switch
    self.cameraScanningLayer()
}

我遇到的问题是:

1) 加载时相机不在视野中

2)按下按钮后,相机就在视野中,但它总是自动扫描

所以我想到使用全局:

var scanEnabled: Bool = false

然后,当单击该按钮时,将其设置为 true 并启用扫描。

这里有一个草图供引用:

enter image description here

编辑 我的快速修复可能不是正确的方法。

我更换了

 let metadataOutput = AVCaptureMetadataOutput() {...} else {
            failed()
            return
        }

并将其放在 if 语句之间

if (scanEnabled == true) {

        let metadataOutput = AVCaptureMetadataOutput()

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

            metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
            // to use them both wwe need to skip AVMetadataObjectTypeQRCode
            metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeCode39Code]
            scanEnabled = false
        } else {
            failed()
            return
        }
        } 

最佳答案

该教程的作者在这里。我的方法是使用专用的扫描 View Controller ,但我想您希望将其与现有的 View Controller 统一 - 这很好。两种方法都有效。

如果您想始终显示相机界面(即使没有主动识别二维码),那么您计划使用 bool 值来跟踪是否启用扫描是一个不错的选择。我的示例代码有 foundCode()被调用的方法,并且还调用 dismissViewControllerAnimated()当找到代码时。

在您的版本中,您需要制作 foundCode()完成停止扫描、处理解雇等所有工作。然后您可以为您的 scanEnabled 添加支票 bool 值集中在一处。

类似这样的事情应该可以做到:

func foundCode(code: String) {
    if scanCode == true {
        print(code)

        captureSession.stopRunning()
        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        dismissViewControllerAnimated(true, completion: nil)
    }
}

如果您愿意,可以移动 scanCode == true检查到 didOutputMetadataObjects以节省不必要的方法调用。

关于ios - 如何在按下按钮时扫描二维码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34291010/

相关文章:

objective-c - 来自 NSSet 的 NSArray 元素未显示在 TableViewCell 中

ios - PFQuery 与 UITableView 中的多个数组

ios - 发现不支持的类型 - AVMetadataObject

ios - 在 iOS 中隐藏键盘

ios - UITextField 无法正确显示超出范围的文本

ios - nodeAtPoint 错误节点

swift - 向 UIAlertView 添加事件指示器

ios - 在 Swift 中以编程方式添加约束不起作用

android - ZXing 2.0 二维码扫描后启动 fragment

QRCode 中的 Unicode 编码和解码问题