swift學(xué)習(xí)小計(jì)(掃描二維碼)

基于swift3.0

1.創(chuàng)建設(shè)備

//MARK: 繪畫
    lazy var session: AVCaptureSession = {
        let ss = AVCaptureSession()
        return ss
    }()
    //MARK: 設(shè)備
    lazy var device: AVCaptureDevice = {
        let dev = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        return dev!
    }()
    //MARK: 輸入設(shè)備
    lazy var deviceInput: AVCaptureDeviceInput? = {
        
        do {
            let input = try AVCaptureDeviceInput(device: self.device)
            return input
        }catch {
            print(error)
            return nil
        }
        
    }()
    //MARK: 輸出設(shè)備
    lazy var deviceOutput: AVCaptureMetadataOutput = {
        let metaOut = AVCaptureMetadataOutput()
       /* metaOut.metadataObjectTypes = metaOut.availableMetadataObjectTypes
        metaOut.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) 
         這兩句不能寫在
         session.addInput(deviceInput)
         session.addOutput(deviceOutput)
         之前
         */
        return metaOut
    }()

2.創(chuàng)建掃描邊框

//MARK: 邊框
    lazy var imageView: UIImageView = {
        let imgView = UIImageView(image: UIImage(named: "qrcode_border"))
        imgView.frame.origin.x = (self.view.frame.width - 200) * 0.5
        imgView.frame.origin.y = 200
        imgView.frame.size = CGSize(width: 200, height: 200)
        return imgView
    }()

3.添加掃描線和掃描線的動(dòng)畫

lazy var scanLine: UIImageView = {
        let lineImageView = UIImageView(image: UIImage(named: "QRCode_ScanLine"))
        lineImageView.frame = CGRect(x: self.imageView.frame.origin.x, y: self.imageView.frame.origin.y, width: self.imageView.frame.size.width, height: 2)
        return lineImageView
    }()
    func scanAnimation() -> CABasicAnimation {
        let startPoint = CGPoint(x: self.scanLine.center.x, y: self.imageView.frame.origin.y)
        let endPoint = CGPoint(x: self.imageView.center.x, y: self.imageView.frame.maxY - 2)
        
        
        let animation = CABasicAnimation(keyPath: "position")
        animation.fromValue = NSValue(cgPoint: startPoint)
        animation.toValue = NSValue(cgPoint: endPoint)
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        animation.duration = 1
        animation.autoreverses = true
        animation.repeatCount = 10000
        return animation
    }

4.添加預(yù)覽圖層

//MARK: 預(yù)覽圖層
    lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer?.frame = UIScreen.main.bounds
        return layer!
    }()

5.開(kāi)始掃描

func startScan() -> Void {
        if !session.canAddInput(deviceInput) {
            return
        }
        if !session.canAddOutput(deviceOutput) {
        return
        }
        scanLine.layer.add(scanAnimation(), forKey: "haha")
        session.addInput(deviceInput)
        session.addOutput(deviceOutput)
        deviceOutput.metadataObjectTypes = deviceOutput.availableMetadataObjectTypes
        deviceOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        //設(shè)置掃面區(qū)域
        deviceOutput.rectOfInterest = (previewLayer.metadataOutputRectOfInterest(for: self.imageView.frame))
        session.startRunning()
        
    }
 override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        title = "掃描二維碼"
        view.addSubview(imageView)
        view.addSubview(scanLine)
        view.layer.insertSublayer(previewLayer, at: 0)
        startScan()
    }

6.掃面完成后的代理(沒(méi)仔細(xì)處理)

extension QRCodeViewController : AVCaptureMetadataOutputObjectsDelegate {
    public func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
//        [<AVMetadataMachineReadableCodeObject: 0x16e67be0, type="org.iso.QRCode", bounds={ 0.6,0.2 0.3x0.6 }>corners { 0.6,0.8 0.9,0.8 0.9,0.2 0.6,0.2 }, time 149347505505458, stringValue "http://weixin.qq.com/r/ydlCWn3EqSDWrTk594zb"]
        if metadataObjects == nil || metadataObjects.count == 0 {
        return
        }
        for object in metadataObjects {
            if object is AVMetadataMachineReadableCodeObject {
                let metadataObj = metadataObjects.last as! AVMetadataMachineReadableCodeObject
//                print(metadataObj.corners)
                
                let pointS : AVMetadataMachineReadableCodeObject = previewLayer.transformedMetadataObject(for: metadataObj) as! AVMetadataMachineReadableCodeObject
                drawCorners(codeObject: pointS)
            }
        }

    }
    private func drawCorners(codeObject: AVMetadataMachineReadableCodeObject) {
        clearSubView()
        let layer = CAShapeLayer()
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = UIColor.red.cgColor
        let pointDic  = codeObject.corners
//        let poindArr = CGPoint.init(dictionaryRepresentation: pointDic)
        let aa = pointDic![0] as! NSDictionary
        let point0 = CGPoint.init(dictionaryRepresentation: aa)
        
        let bb = pointDic![1] as! NSDictionary
        let point1 = CGPoint.init(dictionaryRepresentation: bb)
        
        let cc = pointDic![2] as! NSDictionary
        let point2 = CGPoint.init(dictionaryRepresentation: cc)
        
        let dd = pointDic![3] as! NSDictionary
        let point3 = CGPoint.init(dictionaryRepresentation: dd)
        
    
        
        let path = UIBezierPath()
        path.move(to: point0!)
        path.addLine(to: point1!)
        path.addLine(to: point2!)
        path.addLine(to: point3!)
        path.close()
        layer.path = path.cgPath
        drawLayer.addSublayer(layer)

    }
    func clearSubView() -> Void {
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0{
            return
        }
        for subLayer in drawLayer.sublayers! {
            subLayer.removeFromSuperlayer()
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Core Animation編程指南 關(guān)于Core Animation Core Animation自身并不是一個(gè)...
    錢噓噓閱讀 1,333評(píng)論 0 12
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,261評(píng)論 4 61
  • 你是那漂泊的船兒 我是那靜水的海灣 波濤洶涌記得歸來(lái) 雨過(guò)天晴再去揚(yáng)帆
    O物非人是O閱讀 203評(píng)論 2 3
  • 前些日子忙擼香水,也或許是相似性,孤兒怨的到來(lái)讓我十分欣喜。官網(wǎng)簡(jiǎn)介是灰燼的味道,一入鼻便愛(ài)上。 ...
    琉璃子ssr閱讀 341評(píng)論 0 0
  • 人生不滿百,常懷千歲憂。經(jīng)??紤]未來(lái)是件好事,不過(guò)也不要太過(guò)于擔(dān)心了,事情都會(huì)循著它該有的軌跡發(fā)展。今天,有人問(wèn)我...
    小包包雜記閱讀 306評(píng)論 0 0

友情鏈接更多精彩內(nèi)容