iOS自带原生二维码扫描的实现

下面就是详细讲解iOS自带原生二维码扫描的实现的完整攻略:

一、引入AVFoundation库

首先,我们需要引入AVFoundation库,来实现二维码扫描。在xcode中选择你项目的targets中的Build Phases,在Link Binary With Libraries中添加AVFoundation.framework。

二、继承AVCaptureSession,创建二维码捕捉器

我们需要继承AVCaptureSession,并创建一个二维码捕捉器来扫描二维码。可以看下面的示例:

import AVFoundation

class QRCodeScanner {
    let captureSession = AVCaptureSession()
    var previewLayer: AVCaptureVideoPreviewLayer?

    init() {
        guard let captureDevice = AVCaptureDevice.default(for: .video),
            let input = try? AVCaptureDeviceInput(device: captureDevice) else {
            return
        }

        let captureMetadataOutput = AVCaptureMetadataOutput()
        captureSession.addInput(input)
        captureSession.addOutput(captureMetadataOutput)

        captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        captureMetadataOutput.metadataObjectTypes = [.qr]

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.videoGravity = .resizeAspectFill
        self.previewLayer = previewLayer
    }
}

以上代码中,我们使用AVCaptureSession来创建了一个二维码捕捉器QRCodeScanner。先检测一下设备是否有摄像头,并创建AVCaptureDeviceInput输入设备。然后,创建AVCaptureMetadataOutput对象来检测捕捉到的二维码。最后,创建了一个AVCaptureVideoPreviewLayer预览图层并添加到self.previewLayer中。

三、实现AVCaptureMetadataOutputObjectsDelegate代理方法

接下来,我们需要实现AVCaptureMetadataOutputObjectsDelegate代理方法,来处理捕捉到的二维码。具体代码如下:

extension QRCodeScanner: AVCaptureMetadataOutputObjectsDelegate {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
            let stringValue = metadataObject.stringValue,
            metadataObject.type == .qr else {
            return
        }

        // 二维码扫描成功,可以在这里执行回调
    }
}

以上代码中,我们处理捕捉到的AVMetadataObject,将其转换为二维码AVMetadataMachineReadableCodeObject对象,并获取到二维码的stringValue,来完成二维码的扫描。如果扫描的不是二维码,则直接返回。

四、启动二维码扫描

在上面的QRCodeScanner实现中,我们创建好了AVCaptureSession的输入和输出,以及预览图层。接下来,启动二维码扫描即可:

class ViewController: UIViewController {

    private var qrCodeScanner: QRCodeScanner!

    override func viewDidLoad() {
        super.viewDidLoad()
        qrCodeScanner = QRCodeScanner()

        guard let previewLayer = qrCodeScanner.previewLayer else { return }
        previewLayer.frame = view.layer.bounds
        view.layer.addSublayer(previewLayer)

        qrCodeScanner.captureSession.startRunning()
    }
}

在上面代码中,我们创建了一个QRCodeScanner对象qrCodeScanner,并把预览图层添加到UIViewController的view上。最后,启动QRCodeScanner的捕捉器captureSession即可。

五、示例说明

接下来,我给你两个示例,具体实现请参考上面的完整攻略:

示例1:在UIAlertController中展示扫描到的二维码

在QRCodeScanner中实现接口扫描结束的回调

class QRCodeScanner {
    var onQRCodeScanned: ((String) -> Void)?

    // ...

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
            let stringValue = metadataObject.stringValue,
            metadataObject.type == .qr else {
            return
        }

        // 扫描到二维码,执行回调
        onQRCodeScanned?(stringValue)
    }
}

在UIViewController中弹出UIAlertController,展示扫描到的二维码

class ViewController: UIViewController {

    private var qrCodeScanner: QRCodeScanner!

    override func viewDidLoad() {
        super.viewDidLoad()
        qrCodeScanner = QRCodeScanner()

        qrCodeScanner.onQRCodeScanned = { [weak self] qrCodeString in
            self?.showQRCodeInfo(qrCodeString)
        }

        guard let previewLayer = qrCodeScanner.previewLayer else { return }
        previewLayer.frame = view.layer.bounds
        view.layer.addSublayer(previewLayer)

        qrCodeScanner.captureSession.startRunning()
    }

    private func showQRCodeInfo(_ qrCodeInfo: String) {
        let alertController = UIAlertController(title: "扫描到的二维码", message: qrCodeInfo, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "确定", style: .default, handler: nil)
        alertController.addAction(okAction)

        present(alertController, animated: true, completion: nil)
    }
}

示例2:在UITableView中展示扫描到的二维码

在QRCodeScanner中实现接口扫描结束的回调

class QRCodeScanner {
    var onQRCodeScanned: ((String) -> Void)?

    // ...

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
            let stringValue = metadataObject.stringValue,
            metadataObject.type == .qr else {
            return
        }

        // 扫描到二维码,执行回调
        onQRCodeScanned?(stringValue)
    }
}

在UIViewController中添加UITableView,并更新数据源展示二维码信息

class ViewController: UIViewController {

    private var qrCodeScanner: QRCodeScanner!
    private var qrCodeStrings = [String]() {
        didSet {
            tableView.reloadData()
        }
    }
    private let tableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()
        qrCodeScanner = QRCodeScanner()

        qrCodeScanner.onQRCodeScanned = { [weak self] qrCodeString in
            self?.qrCodeStrings.append(qrCodeString)
        }

        guard let previewLayer = qrCodeScanner.previewLayer else { return }
        previewLayer.frame = view.layer.bounds
        view.layer.addSublayer(previewLayer)

        qrCodeScanner.captureSession.startRunning()

        setupTableView()
    }

    private func setupTableView() {
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "qrCodeCell")
        tableView.dataSource = self
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return qrCodeStrings.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "qrCodeCell", for: indexPath)
        let qrCodeString = qrCodeStrings[indexPath.row]
        cell.textLabel?.text = qrCodeString
        return cell
    }
}

以上示例代码很简单,你可以尝试在自己的项目中按照上述方法实现iOS自带原生二维码扫描。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:iOS自带原生二维码扫描的实现 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • React中DOM事件和状态介绍

    React中DOM事件和状态介绍攻略 React是一个流行的JavaScript库,用于构建用户界面。在React中,DOM事件和状态是两个重要的概念。本攻略将详细介绍React中的DOM事件和状态,并提供两个示例说明。 DOM事件 在React中,DOM事件是与用户交互相关的操作,例如点击、鼠标移动等。React通过使用事件处理函数来处理DOM事件。以下是…

    other 2023年8月21日
    00
  • c#winform中label自动换行解决方法

    以下是C# WinForm中Label自动换行解决方法的完整攻略,包括两个示例说明。 1. C# WinForm中Label自动换行简介 在C# WinForm中,Label控件用于显示文本内容。当文本内容过长时,Label控件默认不会自动换行,而是会将文本内容截断。为了解决这个问题,需要对Label控件进行设置,使其能够自动换行。 2. C# WinFor…

    other 2023年5月9日
    00
  • QT开发应用程序的欢迎界面实例

    非常高兴能为你讲解“QT开发应用程序的欢迎界面实例”的完整攻略。 开发应用程序时,欢迎界面是非常重要的。它是用户界面的第一印象,可以吸引用户的注意力,提高用户体验。本攻略将向你展示如何使用QT框架创建一个漂亮的欢迎界面。 一、创建项目 1.新建一个QtWidgets应用程序项目。 2.在新项目向导的“项目配置”页面,勾选“创建欢迎界面”选项,并指定其为“Ma…

    other 2023年6月25日
    00
  • C++零基础精通数据结构之带头双向循环链表

    C++零基础精通数据结构之带头双向循环链表 什么是带头双向循环链表? 带头双向循环链表是一个常见的数据结构,它可以用来实现链表和队列等数据结构。带头双向循环链表的特点是: 每个节点有两个指针,一个指向前一个节点,一个指向后一个节点。 链表中有一个头节点,但是它不存储数据。 链表的尾节点指向头节点,头节点的前一个节点指向链表的尾节点。这样就形成了一个循环。 怎…

    other 2023年6月27日
    00
  • C语言每日练习之二叉堆

    C语言每日练习之二叉堆 什么是二叉堆? 二叉堆是一种特殊的二叉树,它满足两个特性: 堆的父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值; 堆总是一棵完全二叉树。 实现二叉堆 数据结构 为了实现二叉堆,我们需要先定义数据结构。二叉堆常常使用数组来表示,数组中第一个元素一般为根节点,其余元素依次为树中其它节点的值。通过数组下标计算节点间的关系,可以…

    other 2023年6月27日
    00
  • 什么是dmips

    什么是DMIPS? DMIPS(Dhrystone Millions of Instructions Per Second,德瑞斯通每秒执行百万条指令数)是一种基准测试方法,用于评估计算机处理器的性能。DMIPS是以1970年代流行的Dhrystone测试为基础,并采用了更现代化的测试策略。 Dhrystone测试 Dhrystone是一种通用性能测试标准,…

    其他 2023年3月29日
    00
  • Vue+element-ui添加自定义右键菜单的方法示例

    下面我将详细讲解如何在Vue和element-ui的项目中,添加自定义右键菜单的方法。 前提条件 在开始之前,确保你已经完成了如下操作: 已搭建好Vue和element-ui项目 已经安装好vue-contextmenu插件 如果你还没有完成上述工作,请先完成这些步骤。 添加插件 首先,我们需要安装并引入vue-contextmenu插件。你可以通过npm进…

    other 2023年6月27日
    00
  • iOS 14.2/iPadOS14.2 Beta4值得升级吗?iOS 14.2/iPadOS14.2 Beta4更新详解

    iOS 14.2/iPadOS 14.2 Beta 4 值得升级吗? 简介 iOS 14.2/iPadOS 14.2 Beta 4 是苹果公司最新发布的测试版本,旨在为iPhone和iPad用户提供更好的使用体验。在决定是否升级之前,我们需要考虑以下几个因素。 新功能和改进 iOS 14.2/iPadOS 14.2 Beta 4 带来了一些新功能和改进,这些…

    other 2023年7月27日
    00
合作推广
合作推广
分享本页
返回顶部