iOS 实现扫一扫功能

作者: icbbetter | 来源:发表于2016-07-07 16:51 被阅读1280次
IMG_1842.PNG

iOS 实现扫一扫功能要用到如下几个对象:

 var device: AVCaptureDevice!//设备
 var input: AVCaptureDeviceInput!//输入
 var output: AVCaptureMetadataOutput!//输出
 var session: AVCaptureSession!//连接输出输入
 var preview: AVCaptureVideoPreviewLayer!//页面显示

然后基本配置如下:

16:40:19.jpg 16:47:36.jpg

扫描结果的代理:


16:49:22.jpg

下面贴上所有代码:


import UIKit
import AVFoundation

class ScanQRCodeViewController: BaseViewController {
 
 var device: AVCaptureDevice!
 var input: AVCaptureDeviceInput!
 var output: AVCaptureMetadataOutput!
 var session: AVCaptureSession!
 var preview: AVCaptureVideoPreviewLayer!
 lazy var loading: UIActivityIndicatorView = {
  let view = UIActivityIndicatorView(activityIndicatorStyle: .White)
  view.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
  view.center = CGPoint(x: self.view.center.x, y: self.view.center.y - 100)
  view.hidesWhenStopped = true
  self.view.addSubview(view)
  return view
 }()
 
 override func viewDidLoad() {
  super.viewDidLoad()
  
  view.backgroundColor = UIColor.grayColor()
  
  /**
   配置扫一扫
   */
  setupCamera()
  
  // Do any additional setup after loading the view.
 }
 
 override func didReceiveMemoryWarning() {
  super.didReceiveMemoryWarning()
  // Dispose of any resources that can be recreated.
 }
 
 func setupCamera() {
  loading.startAnimating()
  
  dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) {
   
   self.device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
   
   do { self.input = try AVCaptureDeviceInput(device: self.device) } catch { }
   
   self.output = AVCaptureMetadataOutput()
   self.output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
   
   self.session = AVCaptureSession()
   self.session.sessionPreset = AVCaptureSessionPresetHigh
   
   if self.session.canAddInput(self.input) {
    self.session.addInput(self.input)
   }
   
   if self.session.canAddOutput(self.output) {
    self.session.addOutput(self.output)
   }
   self.output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
   self.preview = AVCaptureVideoPreviewLayer(session: self.session)
   self.preview.frame = self.view.bounds
   self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill
   
   dispatch_async(dispatch_get_main_queue(), {
    self.loading.stopAnimating()
    
    self.view.layer.addSublayer(self.preview)
    
    let rect = CGRect(x: (kScreenW - 250) / 2, y: (kScreenH - 400) / 2, width: 250, height: 250) // 可以扫描的区域
    
    let maskView = UIView(frame: self.view.bounds)
    maskView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
    self.view.addSubview(maskView)
    
    // 配置不能扫描区域的遮罩
    let path = UIBezierPath(rect: self.view.bounds)
    path.appendPath(UIBezierPath(rect: rect).bezierPathByReversingPath())
    
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = path.CGPath
    maskView.layer.mask = shapeLayer
    
    self.output.rectOfInterest = self.preview.metadataOutputRectOfInterestForRect(rect) // 把layer中的坐标系转换成output的坐标系
    let scanAreaImageView = UIImageView(frame: rect) // 扫描框的图片
    scanAreaImageView.image = UIImage(named: "contact_scanframe")
    self.view.addSubview(scanAreaImageView)
    
    /// 上下扫动条
    let sweepLineView = UIImageView(frame: CGRect(x: 1, y: 20, width: 248, height: 2))
    sweepLineView.image = UIImage(named: "line")
    scanAreaImageView.addSubview(sweepLineView)
    
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(1)
    UIView.setAnimationRepeatAutoreverses(true)
    UIView.setAnimationRepeatCount(10000)
    UIView.setAnimationCurve(.EaseInOut)
    sweepLineView.frame = CGRect(x: 1, y: 230, width: 248, height: 2)
    UIView.commitAnimations()
    
    self.session.startRunning() // 开始扫描
    
   })
   
  }
  
 }
 
// }
 
 /*
  // MARK: - Navigation

  // In a storyboard-based application, you will often want to do a little preparation before navigation
  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  // Get the new view controller using segue.destinationViewController.
  // Pass the selected object to the new view controller.
  }
  */
 
}

extension ScanQRCodeViewController: AVCaptureMetadataOutputObjectsDelegate {
 func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
  var stringValue = ""
  if metadataObjects.count > 0 {
   
   dPrint(metadataObjects)
   
   stringValue = metadataObjects[0].stringValue
   
  }
  session.stopRunning()
  
  dPrint(stringValue)
  
 }
 
}

所需要的图片:


line@2x contact_scanframe@2x.png

相关文章

网友评论

  • LionNeo_Liu:微信扫一扫中当光线不足时显示点亮手电筒,这个用的是哪个挨批,请问大神
  • 贱精先玍丶:有没有OC版的

本文标题:iOS 实现扫一扫功能

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