swift二维码的实现

在项目中经常用到二维码的扫描,这里测试了下swift下二维码的实现

  1. 首先在界面中定义一个扫描的区域的View,一般这个区域放到界面的正中间
class ScanView: UIView 
    /// 扫描的区域的宽度
    var scanWidth:CGFloat = 300
    /// 扫描区域
    var scanCenterView:UIView?
    /// 扫描背景边框
    var scanBoard:UIImageView?
    /// 扫描的动态图片
    var scanImageView:UIImageView?

override init(frame: CGRect) {
        super.init(frame: frame)
//-------------------------- 扫描区域的视图---------------------
        //添加扫描区域
        scanCenterView = UIView(frame: CGRect(x: 0, y: 0, width: scanWidth, height: scanWidth))
        scanCenterView?.center=center
        //超出部分剪去
        scanCenterView?.clipsToBounds=true
        addSubview(scanCenterView!)

        //扫描边框
        scanBoard=UIImageView(frame: CGRectMake(scanCenterView!.frame.origin.x-2, scanCenterView!.frame.origin.y-2, scanCenterView!.frame.size.width+3, scanCenterView!.frame.size.height+3))
//        scanBoard?.backgroundColor=UIColor.redColor()
        scanBoard?.image=UIImage(named: "qrcode_border")
        //超出部分剪去
        scanBoard?.clipsToBounds=true
        addSubview(scanBoard!)
    }

2.为了使得扫描的界面更好看,使得扫描框周边的界面半透明化

override func drawRect(rect: CGRect) {
        super.drawRect(rect)

        //得到图形上下文
        let context=UIGraphicsGetCurrentContext()
        ///非扫码区域半透明
        CGContextSetRGBFillColor(context, 0, 0, 0, 0.5)

        let leftMargin = (frame.size.width-scanWidth)/2
        let topMargin = (frame.size.height-scanWidth)/2
        //填充矩形
        //扫码区域上面填充
        var rect = CGRectMake(0, 0, frame.size.width, topMargin)
        CGContextFillRect(context, rect)

        //扫码区域左边填充
        rect=CGRectMake(0, topMargin, leftMargin, frame.size.height-      topMargin*2)
        CGContextFillRect(context, rect)

        //扫码区域右边填充
        rect=CGRectMake(leftMargin+scanWidth, topMargin, leftMargin, frame.size.height-topMargin*2)
        CGContextFillRect(context, rect)

        //扫码区域下面填充
        rect = CGRectMake(0, topMargin+scanWidth, frame.size.width,topMargin)
        CGContextFillRect(context, rect)
        //执行绘画
        CGContextStrokePath(context)
    }

3.同时定义一个扫描的动画,看上去更生动,类似正在扫描一样

/**
    开始动画
     */
 private func startAnimation(){
        UIView.animateWithDuration(1.3) { () -> Void in

        UIView.setAnimationRepeatCount(MAXFLOAT)
                                       self.scanImageView?.frame=CGRectMake(self.scanImageView!.frame.origin.x, self.scanImageView!.frame.origin.y+self.scanCenterView!.frame.size.height+100, (self.scanImageView?.frame.size.width)!, (self.scanImageView?.frame.size.height)!)

        }
    }

    /**
     停止动画
     */
    func stopAnimation()
    {
        scanImageView?.removeFromSuperview()
    }
  1. 在自定义的扫描区域View构建完成后,现在开始调用这个界面进行扫描,在调用之前要调用系统的相机AVCaptureDevice,初始化一些参数
class ViewController: UIViewController{
    /// 扫描视图
    var scanView:ScanView!
    /// 扫描设备
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
     // MARK: - 懒加载
    private lazy var input: AVCaptureDeviceInput? = {
        return try? AVCaptureDeviceInput(device: self.device)
    }()
    // 会话
    private lazy var session : AVCaptureSession = AVCaptureSession()
    // 创建预览图层
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()

    private lazy var output:AVCaptureMetadataOutput = {

        let out = AVCaptureMetadataOutput()

        let viewRect = self.view.frame
        // 扫描区域 (也是扫描框的frame)
        let scanRect = self.scanView.scanCenterView?.frame

        let x = scanRect!.origin.y / viewRect.height;
        let y = scanRect!.origin.x / viewRect.width;
        let width = scanRect!.height / viewRect.height;
        let height = scanRect!.width / viewRect.width;
        // 设置可探测区域
        // rectOfInterset设置: CGRectMake(扫描区域y的起点/屏幕的高度, 扫描区域的x/屏幕的宽度, 扫描区域的高/屏幕的高, 扫描区域的宽度/屏幕的宽度)
        out.rectOfInterest = CGRect(x: x, y: y, width: width, height: height)

        return out
    }()
}
  1. 开始调用扫描二维码
/**
         初始化二维码
     */
    private func scanQRCode(){

        // 1.判断输入能否添加到会话中
        if !session.canAddInput(input){
            return
        }

        // 2.判断输出能够添加到会话中
        if !session.canAddOutput(output)
        {
            return
        }
        // 3.添加输入和输出到会话中
        session.addInput(input)
        session.addOutput(output)


        // 4.设置输出能够解析的数据类型
        // 注意点: 设置数据类型一定要在输出对象添加到会话之后才能设置
//        output.metadataObjectTypes =
//            [AVMetadataObjectTypeQRCode,
//                AVMetadataObjectTypeCode39Code,
//                AVMetadataObjectTypeCode128Code,
//                AVMetadataObjectTypeCode93Code,
//                AVMetadataObjectTypeCode39Mod43Code,
//                AVMetadataObjectTypeEAN8Code,
//                AVMetadataObjectTypeEAN13Code]
        output.metadataObjectTypes = output.availableMetadataObjectTypes

        // 5.设置监听监听输出解析到的数据
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())

        // 6.添加预览图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        previewLayer.frame = view.bounds

        // 7.添加容器图层
        view.layer.addSublayer(containerLayer)
        containerLayer.frame = view.bounds

        // 8.开始扫描
        session.startRunning()

    }

6.对于扫描的结果在其代理方法中实现

//MARK: - AVCaptureMetadataOutputObjectsDelegate
extension ViewController : AVCaptureMetadataOutputObjectsDelegate{
    /// 只要扫描到结果就会调用
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!)
    {
        // 1.显示结果

        print("-----扫描到的------");
        let alertView = UIAlertView(title:"", message: "", delegate: self, cancelButtonTitle: "确定")
        if metadataObjects.count>0 {
            let metadataObject = metadataObjects.last

            if metadataObject!.isKindOfClass(AVMetadataMachineReadableCodeObject) {

                let code = metadataObject as! AVMetadataMachineReadableCodeObject

                print(code)
                //码类型  Code128  QRCode
                print("码类型\(code.type)")
                //码内容
                print("码内容\(code.stringValue)")

                alertView.message=code.stringValue
                alertView.show()

 //4个字典,分别 左上角-右上角-右下角-左下角的 坐标百分百,可以使用这个比例抠出码的图像  code.corners
                //如果是个网址的话 打开这个网址
//                UIApplication.sharedApplication().openURL(NSURL(string: code.stringValue)!)
                scanView.stopAnimation()
                session.stopRunning()

            }
         }
   }
}

通过代理方法可以用来处理扫描到的结果在进行相关的处理
源码可以去这查看https://github.com/Cutehf/QRCode-Swift

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值