ios - 将二维码加载到多 View Controller (Xcode)

标签 ios swift xcode qr-code

我目前正在开发一个项目(使用 Xcode-Swift),需要为某个事件开发一个二维码扫描仪测验应用程序。用户必须分别扫描10个展位的10个二维码(1个展位有1个二维码,1个展位有1个qn)。因此,我有 10 个不同的二维码图像,我可以知道如何根据扫描的二维码打开特定 Controller 吗?截至目前,我的二维码扫描仪只能将二维码扫描到网址。我已经完成了测验 qns 的布局和按钮,我只需要 QR 代码来链接到我的 QuestionControllers。先感谢您。

这是我的 QRScannerController.swift

import UIKit
import AVFoundation

class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    @IBOutlet var messageLabel:UILabel!
    @IBOutlet var topbar: UIView!

    var captureSession:AVCaptureSession?
    var videoPreviewLayer:AVCaptureVideoPreviewLayer?
    var qrCodeFrameView:UIView?

    let supportedCodeTypes = [AVMetadataObjectTypeUPCECode,
                        AVMetadataObjectTypeCode39Code,
                        AVMetadataObjectTypeCode39Mod43Code,
                        AVMetadataObjectTypeCode93Code,
                        AVMetadataObjectTypeCode128Code,
                        AVMetadataObjectTypeEAN8Code,
                        AVMetadataObjectTypeEAN13Code,
                        AVMetadataObjectTypeAztecCode,
                        AVMetadataObjectTypePDF417Code,
                        AVMetadataObjectTypeQRCode]

    override func viewDidLoad() {
        super.viewDidLoad()

        // 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 {
            // Get an instance of the AVCaptureDeviceInput class using the previous device object.
            let input = try AVCaptureDeviceInput(device: captureDevice)

            // Initialize the captureSession object.
            captureSession = AVCaptureSession()

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

            // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
            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 = supportedCodeTypes

            // Initialize 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()

            // Move the message label and top bar to the front
            view.bringSubview(toFront: messageLabel)
            view.bringSubview(toFront: topbar)

            // 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)
            }

        } catch {
            // If any error occurs, simply print it out and don't continue any more.
            print(error)
            return
        }
    }

    // MARK: - AVCaptureMetadataOutputObjectsDelegate Methods

    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/barcode is detected"
            return
        }

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

        if supportedCodeTypes.contains(metadataObj.type) {
            // 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 {
                let url = URL(string: metadataObj.stringValue)!
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(url, options: [:], completionHandler: nil)
                } else {
                    UIApplication.shared.openURL(url)
                }
            }
        }
    }
}

这是我的问题 Controller

import UIKit    
class Quiz1Controller: UIViewController {    
    override func viewDidLoad() {
        super.viewDidLoad()    
    }
}

Image of QrCodeScanner and Question views

最佳答案

问:我可以知道如何根据扫描的二维码打开特定 Controller 吗?

我建议您创建一个 QR 扫描仪类和一个委托(delegate)。然后创建一个“流程 Controller ”,它将控制您的应用程序流程,例如读取 QR x 将显示 Controller x 等等。一些想法:

警告:未经测试的代码

protocol QRHandler {
    func didRead(qr: String)
}

class QRCodeScanner {
    weak var delegate: QRHandler?

    func startScan() {
        // your scan code
        // if qr read
        delegate?.didRead(qr: qrRead)
    }
}

class FlowController: UINavagationController /*or UITabBarController or something else you want*/ {
    private var currentVC: String
    private let scanner = QRCodeScanner()

    func init() {
        scanner.delegate = self
        scanner.startScan()
    }

    // MARK: - QRHandler
    func didRead(qr: String) {
        switch currentVC {
            case "X":
                // present Y
            case "Y":
                // present Z
            default:
                // unexpected vc...
        }
    }
}

关于ios - 将二维码加载到多 View Controller (Xcode),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45284970/

相关文章:

ios - 如何在 textfieldDidEndEditing 上调用方法

ios - Oauth 失败后的 AlamoFire 重试请求

ios - 绘制将在 objective-c 中绘制头骨的动画

swift - 为沙盒用户获取 App Store 收据失败,并显示错误的密码消息

ios - 绘制 CIImage 的背景颜色

objective-c - 如何将 NSData 转换为 NSString?

ios - 使用生成功能为图像添加动画

swift - 限制非高级用户每天只能写入一次 firebase 数据库

iphone - 选择 UIPickerView 项目时运行 ibaction

iphone - 带有旋转 UI 元素的 AutoLayout