LBXScanViewController.swift 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //
  2. // LBXScanViewController.swift
  3. // swiftScan
  4. //
  5. // Created by lbxia on 15/12/8.
  6. // Copyright © 2015年 xialibing. All rights reserved.
  7. //
  8. import UIKit
  9. import Foundation
  10. import AVFoundation
  11. public protocol LBXScanViewControllerDelegate: class {
  12. func scanFinished(scanResult: LBXScanResult, error: String?)
  13. }
  14. public protocol QRRectDelegate {
  15. func drawwed()
  16. }
  17. open class LBXScanViewController: UIViewController {
  18. // 返回扫码结果,也可以通过继承本控制器,改写该handleCodeResult方法即可
  19. open weak var scanResultDelegate: LBXScanViewControllerDelegate?
  20. open var delegate: QRRectDelegate?
  21. open var scanObj: LBXScanWrapper?
  22. open var scanStyle: LBXScanViewStyle? = LBXScanViewStyle()
  23. open var qRScanView: LBXScanView?
  24. // 启动区域识别功能
  25. open var isOpenInterestRect = false
  26. // 识别码的类型
  27. public var arrayCodeType: [AVMetadataObject.ObjectType]?
  28. // 是否需要识别后的当前图像
  29. public var isNeedCodeImage = false
  30. // 相机启动提示文字
  31. public var readyString: String! = "loading"
  32. open override func viewDidLoad() {
  33. super.viewDidLoad()
  34. // Do any additional setup after loading the view.
  35. // [self.view addSubview:_qRScanView];
  36. view.backgroundColor = UIColor.black
  37. edgesForExtendedLayout = UIRectEdge(rawValue: 0)
  38. }
  39. open func setNeedCodeImage(needCodeImg: Bool) {
  40. isNeedCodeImage = needCodeImg
  41. }
  42. // 设置框内识别
  43. open func setOpenInterestRect(isOpen: Bool) {
  44. isOpenInterestRect = isOpen
  45. }
  46. open override func viewDidAppear(_ animated: Bool) {
  47. super.viewDidAppear(animated)
  48. drawScanView()
  49. perform(#selector(LBXScanViewController.startScan), with: nil, afterDelay: 0.3)
  50. }
  51. @objc open func startScan() {
  52. if scanObj == nil {
  53. var cropRect = CGRect.zero
  54. if isOpenInterestRect {
  55. cropRect = LBXScanView.getScanRectWithPreView(preView: view, style: scanStyle!)
  56. }
  57. // 指定识别几种码
  58. if arrayCodeType == nil {
  59. arrayCodeType = [AVMetadataObject.ObjectType.qr as NSString,
  60. AVMetadataObject.ObjectType.ean13 as NSString,
  61. AVMetadataObject.ObjectType.code128 as NSString] as [AVMetadataObject.ObjectType]
  62. }
  63. scanObj = LBXScanWrapper(videoPreView: view,
  64. objType: arrayCodeType!,
  65. isCaptureImg: isNeedCodeImage,
  66. cropRect: cropRect,
  67. success: { [weak self] (arrayResult) -> Void in
  68. guard let strongSelf = self else {
  69. return
  70. }
  71. // 停止扫描动画
  72. strongSelf.qRScanView?.stopScanAnimation()
  73. strongSelf.handleCodeResult(arrayResult: arrayResult)
  74. })
  75. }
  76. // 结束相机等待提示
  77. qRScanView?.deviceStopReadying()
  78. // 开始扫描动画
  79. qRScanView?.startScanAnimation()
  80. // 相机运行
  81. scanObj?.start()
  82. }
  83. open func drawScanView() {
  84. if qRScanView == nil {
  85. qRScanView = LBXScanView(frame: view.frame, vstyle: scanStyle!)
  86. view.addSubview(qRScanView!)
  87. delegate?.drawwed()
  88. }
  89. qRScanView?.deviceStartReadying(readyStr: readyString)
  90. }
  91. /**
  92. 处理扫码结果,如果是继承本控制器的,可以重写该方法,作出相应地处理,或者设置delegate作出相应处理
  93. */
  94. open func handleCodeResult(arrayResult: [LBXScanResult]) {
  95. guard let delegate = scanResultDelegate else {
  96. fatalError("you must set scanResultDelegate or override this method without super keyword")
  97. }
  98. navigationController?.popViewController(animated: true)
  99. if let result = arrayResult.first {
  100. delegate.scanFinished(scanResult: result, error: nil)
  101. } else {
  102. let result = LBXScanResult(str: nil, img: nil, barCodeType: nil, corner: nil)
  103. delegate.scanFinished(scanResult: result, error: "no scan result")
  104. }
  105. }
  106. open override func viewWillDisappear(_ animated: Bool) {
  107. NSObject.cancelPreviousPerformRequests(withTarget: self)
  108. qRScanView?.stopScanAnimation()
  109. scanObj?.stop()
  110. }
  111. @objc open func openPhotoAlbum() {
  112. LBXPermissions.authorizePhotoWith { [weak self] _ in
  113. let picker = UIImagePickerController()
  114. picker.sourceType = UIImagePickerController.SourceType.photoLibrary
  115. picker.delegate = self
  116. picker.allowsEditing = true
  117. self?.present(picker, animated: true, completion: nil)
  118. }
  119. }
  120. }
  121. //MARK: - 图片选择代理方法
  122. extension LBXScanViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
  123. //MARK: -----相册选择图片识别二维码 (条形码没有找到系统方法)
  124. public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
  125. picker.dismiss(animated: true, completion: nil)
  126. let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
  127. let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
  128. guard let image = editedImage ?? originalImage else {
  129. showMsg(title: nil, message: NSLocalizedString("Identify failed", comment: "Identify failed"))
  130. return
  131. }
  132. let arrayResult = LBXScanWrapper.recognizeQRImage(image: image)
  133. if !arrayResult.isEmpty {
  134. handleCodeResult(arrayResult: arrayResult)
  135. }
  136. }
  137. }
  138. //MARK: - 私有方法
  139. private extension LBXScanViewController {
  140. func showMsg(title: String?, message: String?) {
  141. let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
  142. let alertAction = UIAlertAction(title: NSLocalizedString("OK", comment: "OK"), style: .default, handler: nil)
  143. alertController.addAction(alertAction)
  144. present(alertController, animated: true, completion: nil)
  145. }
  146. }