美文网首页集思广益iOS开发iOS Developer
【iOS】swift3.0实现二维码扫描完美版

【iOS】swift3.0实现二维码扫描完美版

作者: 清無 | 来源:发表于2017-04-21 10:46 被阅读358次

    效果:

    iPad横屏

    要求:

    • Platform: iOS8.0+
    • Language: Swift3.0
    • Editor: Xcode8
    • Adaptive: 适配横竖屏+所有设备

    用法:

    先向你新建的工程Info.plist中添加相机和相册访问权限
    • 代码方式
    let vc = QRCodeViewController {[unowned self] (result) in
         print("扫描结果: \(result)")
    }
    // 显示扫一扫界面
    present(vc, animated: true, completion: nil)
    
    • 或者storyboard方式
    在storyboard上拖拽一个viewcontroller
    override func prepare(for segue: UIStoryboardSegue, sender: Any?){
          if let vc = segue.destination as? QRCodeViewController{
              vc.completion = {[unowned self](result)in
                  print("扫描结果: \(result)")
              }
          }
    }
    

    原理:

    • xib布局 + AVFoundation
    • xib布局
    竖屏 横屏
    • 扫描框和扫描线均为UIImageView,可自行替换
    扫描框图
    • 支持手电筒照明功能
    • 核心代码
    // QRCodeReader.swift
    //1. 视频捕获设备
        public let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        
     //2. 捕获元数据输出对象
        public lazy var output: AVCaptureMetadataOutput = {
            let v = AVCaptureMetadataOutput()
            v.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            return v
        }()
    
    //3. 捕获会话对象
        public lazy var session: AVCaptureSession = {
            let v = AVCaptureSession()
            v.sessionPreset = AVCaptureSessionPresetHigh
            
            if let input = try? AVCaptureDeviceInput(device: self.device),
                v.canAddInput(input){
                v.addInput(input)
            }
            if v.canAddOutput(self.output) {
                v.addOutput(self.output)
                if !self.output.availableMetadataObjectTypes.isEmpty {
                    self.output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
                }
            }
            
            return v
        }()
        
    //4. 视频预览层视图
        public lazy var previewLayer: AVCaptureVideoPreviewLayer = {
            let v = AVCaptureVideoPreviewLayer(session: self.session)
            v?.videoGravity = AVLayerVideoGravityResizeAspectFill
            v?.connection.videoOrientation = self.videoOrientation(interfaceOrientation: UIApplication.shared.statusBarOrientation)
            return v!
        }()
    
    
    • 关键公用方法
    // 开始扫描
        public func startScanning(completion: QRCodeReaderCompletion?){
            self.completion = completion
            self.session.startRunning()
        }
    // 停止扫描
        public func stopScanning(){
            self.session.stopRunning()
        }
    
    • 扫描输出代理方法
    extension QRCodeReader: AVCaptureMetadataOutputObjectsDelegate{
        func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!)
        {
            if !metadataObjects.isEmpty,
                let data = metadataObjects.first as? AVMetadataMachineReadableCodeObject
            {
                stopScanning()
                completion?(data.stringValue)
            }
        }
    }
    

    源码:

    https://github.com/BackWorld/QRCodeScanner

    如果对你有帮助,别忘了点个❤️哦。

    相关文章

      网友评论

        本文标题:【iOS】swift3.0实现二维码扫描完美版

        本文链接:https://www.haomeiwen.com/subject/jvxdzttx.html