概述
ios自定义扫码实现
- 自定义界面
- 初始化相机
- 界面动画
- 实现AVCaptureMetadataOutputObjectsDelegate代理,获取扫码结果
- 扫码成功播放提示音
使用AVFoundation实现扫码读取二维码数据,界面定义使用SnapKit自动布局框架实现。
自定义界面
在controller的viewDidLoad方法中绘制界面组件。
self.title = "二维码/条码"
self.view.backgroundColor = UIColor.black
self.cameraView = UIView()
self.cameraView.backgroundColor = UIColor.clear
self.view.addSubview(self.cameraView)
self.cameraView.snp.makeConstraints { (make) in
make.top.left.right.bottom.equalTo(0)
}
self.scanView = UIView()
self.scanView.backgroundColor = UIColor.clear
self.view.addSubview(self.scanView)
self.scanView.snp.makeConstraints { (make) in
make.centerY.equalTo(self.view.snp.centerY).offset(-20)
make.centerX.equalTo(self.view.snp.centerX)
make.width.height.equalTo(200)
}
let tipLabl = UILabel()
tipLabl.font = UIFont.systemFont(ofSize: 14)
tipLabl.textColor = UIColor.white
tipLabl.textAlignment = .center
tipLabl.numberOfLines = 0
tipLabl.alpha = 1
tipLabl.text = "将二维码/条形码放入框内,即可自动扫描"
self.scanLine = UIView()
self.scanLine.backgroundColor = CommonUtil.colorWithRGB(rgb: 0x2B4B6C, a: 1)
self.view.addSubview(self.scanLine)
self.scanLine.snp.makeConstraints { (make) in
make.top.equalTo(self.scanView.top)
make.left.right.equalTo(self.scanView)
make.width.equalTo(self.scanView.snp.width)
make.height.equalTo(1)
}
let topBg = UIView()
topBg.backgroundColor = UIColor.black
topBg.alpha = 0.8
self.view.addSubview(topBg)
topBg.snp.makeConstraints { (make) in
make.top.equalTo(0)
make.centerX.equalTo(self.view)
make.bottom.equalTo(self.scanView.snp.top)
make.width.equalTo(self.scanView.snp.width)
}
let bottomBg = UIView()
bottomBg.backgroundColor = UIColor.black
bottomBg.alpha = 0.8
self.view.addSubview(bottomBg)
bottomBg.snp.makeConstraints { (make) in
make.centerX.equalTo(self.view)
make.top.equalTo(self.scanView.snp.bottom)
make.bottom.equalTo(0)
make.width.equalTo(self.scanView.snp.width)
}
let leftView = UIView()
leftView.backgroundColor = UIColor.black
leftView.alpha = 0.8
self.view.addSubview(leftView)
leftView.snp.makeConstraints { (make) in
make.top.bottom.equalTo(0)
make.left.equalTo(0)
make.right.equalTo(self.scanView.snp.left)
}
let rightView = UIView()
rightView.backgroundColor = UIColor.black
rightView.alpha = 0.8
self.view.addSubview(rightView)
rightView.snp.makeConstraints { (make) in
make.top.bottom.equalTo(0)
make.left.equalTo(self.scanView.snp.right)
make.right.equalTo(0)
}
self.view.addSubview(tipLabl)
tipLabl.snp.makeConstraints { (make) in
make.top.equalTo(self.scanView.snp.bottom).offset(10)
make.height.greaterThanOrEqualTo(20)
make.left.right.equalTo(self.scanView)
}
初始化相机
在viewDidAppear检查权限、初始化相机、开启界面动画效果
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !self.iniLogic {
self.iniLogic = true
self.initAuthorization()
}
captureSession.startRunning()
self.startAnimate()
}
func initAuthorization() {
if CommonAuthorizationUtils.getInstance().authorizationDeviceStatus(mediaType: AVMediaType.video.rawValue) {
self.initCamera()
captureSession.startRunning()
}else{
self.backBtnClick()
}
}
func initCamera() {
let metadataOutput:AVCaptureMetadataOutput = AVCaptureMetadataOutput()
let input:AVCaptureDeviceInput
do {
input = try AVCaptureDeviceInput(device: self.captureDevice)
}catch{
self.showWithError(message: "初始化失败")
return
}
if captureSession.canAddInput(input) {
captureSession.addInput(input)
}
if captureSession.canAddOutput(metadataOutput) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr,AVMetadataObject.ObjectType.code39,AVMetadataObject.ObjectType.code93,AVMetadataObject.ObjectType.code128,AVMetadataObject.ObjectType.code39Mod43,AVMetadataObject.ObjectType.ean13,AVMetadataObject.ObjectType.ean8]
}
let layer = AVCaptureVideoPreviewLayer(session: captureSession)
layer.videoGravity = AVLayerVideoGravity.resizeAspectFill
layer.frame = self.view.layer.bounds
let scanx = self.scanView.left/self.view.width
let scany = self.scanView.top/self.view.height
let scanWidth = self.scanView.width/self.view.width
let scanHeight = self.scanView.height/self.view.height
let scanRect = CGRect(x: scany, y: scanx, width: scanHeight, height: scanWidth)
metadataOutput.rectOfInterest = scanRect
self.cameraView.layer.insertSublayer(layer, at: 1)
}
界面动画
func startAnimate() {
self.scanLine.isHidden = false
if self.timer == nil {
self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
self.timer?.scheduleRepeating(deadline: .now(), interval: .seconds(2))
self.timer?.setEventHandler(handler: {
self.moveScanLine()
})
}
self.startTimer()
}
func moveScanLine() {
self.scanLine.top = self.scanView.top
UIView.animate(withDuration: 2, animations: {
self.scanLine.top = self.scanView.bottom
})
}
func startTimer() {
self.timer?.resume()
}
func stopTimer() {
self.scanLine.top = self.scanView.top
self.scanLine.isHidden = true
self.timer?.cancel()
self.timer = nil
}
实现AVCaptureMetadataOutputObjectsDelegate代理,获取扫码结果
extension QrScanVC:AVCaptureMetadataOutputObjectsDelegate{
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
self.playTip()
self.stopTimer()
self.captureSession.stopRunning()
if let data = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
self.didScanResult?(data.stringValue ?? "")
self.backBtnClick()
}
}
}
扫码成功播放提示音
func playTip() {
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
do {
if let path = Bundle.main.path(forResource: "scan_done", ofType: "mp3"){
self.avAudioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
self.avAudioPlayer?.delegate = self
self.avAudioPlayer?.volume = 1
self.avAudioPlayer?.numberOfLoops = 1
self.avAudioPlayer?.prepareToPlay()
self.avAudioPlayer?.play()
}
}catch {
debugPrint("play audio error")
}
}
最后
以上就是酷炫猎豹为你收集整理的ios使用AVFoundation自定义实现扫码功能的全部内容,希望文章能够帮你解决ios使用AVFoundation自定义实现扫码功能所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复