Nenhuma Descrição

QRCodeScanView.swift 6.3KB

    // // QRCodeScanView.swift // PaiAi // // Created by mac on 16/7/21. // Copyright © 2016年 FFIB. All rights reserved. // import UIKit import AVFoundation import CoreImage @IBDesignable public class QRCodeScanView: UIView { var qrmaskView: QRCodeMaskView? var qrscanner: QRCodeScanner? var indicatorView: UIActivityIndicatorView = { let indicator = UIActivityIndicatorView(style: .white) indicator.frame = CGRect(x: (UIScreen.main.bounds.width - 100) / 2 , y: (UIScreen.main.bounds.height - 100) / 2, width: 100, height: 100) return indicator }() public var configuration = QRCodeConfiguration() { didSet { qrmaskView?.configuration = configuration } } public weak var delegate: QRCodeScanViewDelegate? let picker = UIImagePickerController() override public func layoutSubviews() { super.layoutSubviews() commonInit() } fileprivate func commonInit() { addSubview(indicatorView) indicatorView.startAnimating() setQRScanner() setMaskView() start() NotificationCenter.default.addObserver(self, selector: #selector(start), name: Notification.QRNotification.RestartNotification, object: nil) } fileprivate func setMaskView() { backgroundColor = UIColor.black qrmaskView = QRCodeMaskView(frame: CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height)) guard let view = qrmaskView else { return } view.configuration = configuration view.backgroundColor = UIColor(r: 0, g: 0, b: 0, a: 0.2) addSubview(view) } fileprivate func setQRScanner() { qrscanner = QRCodeScanner(scanRect: bounds) guard let qrscanner = qrscanner else { return } qrscanner.didDecodeCode = {[weak self] res in if let weakself = self { weakself.delegate?.scanView(weakself, receivedScanResult: res) weakself.qrmaskView?.stopAnimation() weakself.indicatorView.stopAnimating() } } qrscanner.didDecodeFail = {[weak self] error in if let weakself = self { weakself.delegate?.scanView(weakself, didFinshWithError: error) weakself.indicatorView.stopAnimating() } } guard let previewLayer = qrscanner.previewLayer else { return } previewLayer.frame = bounds layer.insertSublayer(previewLayer, at: 0) } @objc func start() { let queue = DispatchQueue(label: "ffib.startScan.com") queue.async { self.qrscanner?.startScan() DispatchQueue.main.async { self.qrmaskView?.startAnimation() self.indicatorView.stopAnimating() } } } public func openLight() { guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return } do { try device.lockForConfiguration() if device.hasTorch && device.isTorchAvailable { if device.isTorchActive { device.torchMode = .off } else { device.torchMode = .on } } } catch { print("open light error") } } public func openPhotoLibrary(ctl: UIViewController) { indicatorView.startAnimating() let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video) if status == .notDetermined || status == .authorized { picker.sourceType = .photoLibrary picker.delegate = self ctl.present(picker, animated: true, completion: nil) } else { let alert = UIAlertController(title: "拒绝访问", message: "请在设置-隐私-相机中允许访问相册", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil)) ctl.present(alert, animated: true, completion: nil) } } } extension QRCodeScanView: UIImagePickerControllerDelegate, UINavigationControllerDelegate { public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { picker.dismiss(animated: true) { guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return } if let res = image.decodeQRCodeInImage() { self.qrscanner?.stopScan() self.qrmaskView?.stopAnimation() self.delegate?.scanView(self, receivedScanResult: QRCodeScanResult(metadataType: AVMetadataObject.ObjectType.qr.rawValue, result: res)) } else { let error = NSError(domain: "decode qr code error", code: 101, userInfo: nil) self.delegate?.scanView(self, didFinshWithError: error) } self.indicatorView.stopAnimating() } } public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true, completion: nil) } } //qr code identify the pictures extension UIImage { /// 识别图片内的二维码 /// /// - Returns: 二维码信息 public func decodeQRCodeInImage() -> String? { guard let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: nil), let cgImage1 = self.cgImage else { return nil } let result = detector.features(in: CIImage(cgImage: cgImage1), options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]) guard let first = (result as? [CIQRCodeFeature])?.first else { return nil } return first.messageString } }