swift 3.0 Xcode 8.1
須要在info.plist 添加 Privacy - Camera Usage Description YES
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var session: AVCaptureSession! //輸入輸出的中間橋樑
var myInput: AVCaptureDeviceInput! //建立輸入流
var myOutput: AVCaptureMetadataOutput! //建立輸出流
var bgView = UIView()
var barcodeView = UIView()
var timer = Timer()
var scanLine = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
//設置定時器,延遲2秒啓動
self.timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(moveScannerLayer(_:)), userInfo: nil, repeats: true)
//初始化連接對象
self.session = AVCaptureSession.init()
//設置高質量採集率
self.session.canSetSessionPreset(AVCaptureSessionPresetHigh)
//獲取攝像設備
let device: AVCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
//捕捉異常,並處理
do {
self.myInput = try AVCaptureDeviceInput.init(device: device)
self.myOutput = AVCaptureMetadataOutput.init()
self.session.addInput(self.myInput)
self.session.addOutput(self.myOutput)
} catch {
print("error")
}
//建立預覽視圖
self.createBackGroundView()
//設置掃描範圍(橫屏)
self.myOutput.rectOfInterest = CGRect(x: 0.35, y: 0.2, width: UIScreen.main.bounds.width * 0.6 / UIScreen.main.bounds.height, height: 0.6)
//設置掃碼支持的編碼格式(以下設置條形碼和二維碼兼容)
myOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]
//建立串行隊列
let dispatchQueue = DispatchQueue(label: "queue", attributes: [])
//設置輸出流的代理
self.myOutput.setMetadataObjectsDelegate(self, queue: dispatchQueue)
//建立預覽圖層
let myLayer = AVCaptureVideoPreviewLayer.init(session: self.session)
myLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill //設置預覽圖層的填充方式
myLayer?.frame = self.view.layer.bounds //設置預覽圖層的frame
self.bgView.layer.insertSublayer(myLayer!, at: 0) //將預覽圖層(攝像頭畫面)插入到預覽視圖的最底部
//開始掃描
self.session.startRunning()
self.timer.fire()
}
//掃描結果,代理
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects != nil && metadataObjects.count > 0 {
//中止掃描
self.session.stopRunning()
timer.invalidate()
//獲取第一個
let metaData = metadataObjects.first as! AVMetadataMachineReadableCodeObject
print(metaData.stringValue)
DispatchQueue.main.async(execute: {
//掃描到以後的操做
//......
print(metaData.stringValue)
})
}
}
//建立預覽視圖
func createBackGroundView() {
self.bgView.frame = UIScreen.main.bounds
self.bgView.backgroundColor = UIColor.black
self.view.addSubview(self.bgView)
//灰色蒙版
let topView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height * 0.35))
let leftView = UIView(frame: CGRect(x: 0, y: UIScreen.main.bounds.size.height * 0.35, width: UIScreen.main.bounds.size.width * 0.2, height: UIScreen.main.bounds.size.width * 0.6))
let rightView = UIView(frame: CGRect(x: UIScreen.main.bounds.size.width * 0.8, y: UIScreen.main.bounds.size.height * 0.35, width: UIScreen.main.bounds.size.width * 0.2, height: UIScreen.main.bounds.size.width * 0.6))
let bottomView = UIView(frame: CGRect(x: 0, y: UIScreen.main.bounds.size.width * 0.6 + UIScreen.main.bounds.size.height * 0.35, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height * 0.65 - UIScreen.main.bounds.size.width * 0.6))
topView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
bottomView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
leftView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
rightView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
//文字說明
let label = UILabel(frame: CGRect(x: 0, y: 10, width: UIScreen.main.bounds.size.width, height: 21))
label.textAlignment = NSTextAlignment.center
label.font = UIFont.systemFont(ofSize: 14)
label.textColor = UIColor.white
label.text = "將二維碼/條形碼放入掃描框內,即自動掃描"
bottomView.addSubview(label)
self.bgView.addSubview(topView)
self.bgView.addSubview(bottomView)
self.bgView.addSubview(leftView)
self.bgView.addSubview(rightView)
//屏幕中間掃描區域視圖(透明)
barcodeView.frame = CGRect(x: UIScreen.main.bounds.size.width * 0.2, y: UIScreen.main.bounds.size.height * 0.35, width: UIScreen.main.bounds.size.width * 0.6, height: UIScreen.main.bounds.size.width * 0.6)
barcodeView.backgroundColor = UIColor.clear
barcodeView.layer.borderWidth = 1.0
barcodeView.layer.borderColor = UIColor.white.cgColor
self.bgView.addSubview(barcodeView)
//掃描線
scanLine.frame = CGRect(x: 0, y: 0, width: barcodeView.frame.size.width, height: 5)
scanLine.image = UIImage(named: "QRCodeScanLine")
barcodeView.addSubview(scanLine)
}
//掃描線滾動
func moveScannerLayer(_ timer : Timer) {
self.scanLine.frame = CGRect(x: 0, y: 0, width: self.barcodeView.frame.size.width, height: 12)
UIView.animate(withDuration: 2) {
self.scanLine.frame = CGRect(x: self.scanLine.frame.origin.x, y: self.scanLine.frame.origin.y + self.barcodeView.frame.size.height - 10, width: self.scanLine.frame.size.width, height: self.scanLine.frame.size.height)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}