最近项目用到了二维码扫码的功能,在网上找了很多Demo,都不是很合适,所以自己基于ZBarSDK进行了封装。下面是封装代码
1.引入ZBarSDK
pod 'ZBarSDK'
pod 'Masonry'//因为自定义界面给用了masonry布局
2.在二维码扫码界面的上层添加自定义视图界面
NKScanQRCodeView.h文件
//
// NKScanQRCodeView.h
// QuickPark-SSP
//
// Created by Nick on 2017/6/2.
// Copyright © 2017年 Nick. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ZBarSDK.h"
@interface NKScanQRCodeView : UIView
//开放给外部的参数
//二维码扫码界面
@property (nonatomic, strong) ZBarReaderView *readerView;
//扫描框
@property (nonatomic, strong) UIImageView *readerImageView;
//扫描线
@property (nonatomic, strong) UIImageView *readLineView;
//扫描线动画控制
@property (nonatomic,assign)BOOL is_Anmotion;
@property (nonatomic,assign)BOOL is_AnmotionFinished;
//实现代理方法的VC
@property (nonatomic, strong) UIViewController *vc;
//开始扫码
- (void)scanStart;
//结束扫码
- (void)scanStop;
@end
NKScanQRCodeView.m文件
//
// NKScanQRCodeView.m
// QuickPark-SSP
//
// Created by Nick on 2017/6/2.
// Copyright © 2017年 Nick. All rights reserved.
//
#import "NKScanQRCodeView.h"
#import "Masonry.h"
//界面的宽
#define WIDTH_VIEW [UIScreen mainScreen].bounds.size.width
//界面的高
#define HEIGHT_VIEW [UIScreen mainScreen].bounds.size.height
//半透明背景色
#define COLOR_BACKBLACK_TRANSPARENT [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]
@implementation NKScanQRCodeView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self initSubViews];
[self initReaderView];
_is_AnmotionFinished = YES;
}
return self;
}
//初始化界面
- (void)initSubViews
{
//二维码扫描界面
_readerView = [ZBarReaderView new];
[self addSubview:_readerView];
[_readerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.mas_centerX);
make.centerY.equalTo(self.mas_centerY);
make.size.mas_equalTo(CGSizeMake(WIDTH_VIEW, HEIGHT_VIEW));
}];
//imageView
UIImageView *readerImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scanframe"]];
self.readerImageView = readerImageView;
[self addSubview:readerImageView];
[readerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.mas_centerX);
make.centerY.equalTo(self.mas_centerY).multipliedBy(0.9);
make.size.mas_equalTo(CGSizeMake(220, 220));
}];
//边背景view
UIView *buttonBaseView = [[UIView alloc] init];
buttonBaseView.backgroundColor = COLOR_BACKBLACK_TRANSPARENT;
[self addSubview:buttonBaseView];
[buttonBaseView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.mas_bottom);
make.centerX.equalTo(self.mas_centerX);
make.size.mas_equalTo(CGSizeMake(WIDTH_VIEW, 91));
}];
UIView *leftView = [[UIView alloc] init];
leftView.backgroundColor = COLOR_BACKBLACK_TRANSPARENT;
[self addSubview:leftView];
[leftView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_top);
make.left.equalTo(self.mas_left);
make.right.equalTo(readerImageView.mas_left);
make.bottom.equalTo(buttonBaseView.mas_top);
}];
UIView *rightView = [[UIView alloc] init];
rightView.backgroundColor = COLOR_BACKBLACK_TRANSPARENT;
[self addSubview: rightView];
[rightView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_top);
make.left.equalTo(readerImageView.mas_right);
make.right.equalTo(self.mas_right);
make.bottom.equalTo(buttonBaseView.mas_top);
}];
UIView *topView = [[UIView alloc] init];
topView.backgroundColor = COLOR_BACKBLACK_TRANSPARENT;
[self addSubview:topView];
[topView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.mas_top);
make.left.equalTo(leftView.mas_right);
make.bottom.equalTo(readerImageView.mas_top);
make.right.equalTo(rightView.mas_left);
}];
UIView *bottomView = [[UIView alloc] init];
bottomView.backgroundColor = COLOR_BACKBLACK_TRANSPARENT;
[self addSubview:bottomView];
[bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(readerImageView.mas_bottom);
make.left.equalTo(leftView.mas_right);
make.bottom.equalTo(buttonBaseView.mas_top);
make.right.equalTo(rightView.mas_left);
}];
//扫描二维码提示
UILabel *msgLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 14)];
[bottomView addSubview:msgLabel];
msgLabel.text = @"将二维码放到区域内自动扫描";
msgLabel.textColor = [UIColor whiteColor];
msgLabel.font = [UIFont systemFontOfSize:14.0];
[msgLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(bottomView.mas_top).offset(10);
make.centerX.equalTo(self.mas_centerX);
make.height.mas_equalTo(14.0);
}];
}
//初始化ZBarReaderView
- (void)initReaderView
{
//扫描区域
CGRect scanMaskRect = CGRectMake(60,CGRectGetMidY(self.readerView.frame) - 126, 300, 300);
//处理模拟器
if (TARGET_IPHONE_SIMULATOR)
{
ZBarCameraSimulator *cameraSimulator
= [[ZBarCameraSimulator alloc] initWithViewController:self.vc];
cameraSimulator.readerView = self.readerView;
}
//扫描区域计算
self.readerView.scanCrop = [self getScanCrop:scanMaskRect readerViewBounds:self.readerView.bounds];
}
//创建扫描条
-(void)loopDrawLine
{
_is_AnmotionFinished = NO;
CGRect rect = CGRectMake(5, 10, _readerImageView.frame.size.width - 10, 2);
if (_readLineView) {
_readLineView.alpha = 1;
_readLineView.frame = rect;
}
else{
_readLineView = [[UIImageView alloc] initWithFrame:rect];
[_readLineView setImage:[UIImage imageNamed:@"scanLine"]];
[_readerImageView addSubview:_readLineView];
}
[UIView animateWithDuration:1.5 animations:^{
_readLineView.frame =CGRectMake(5, _readerImageView.frame.size.height - 10, _readerImageView.frame.size.width - 10, 2);
} completion:^(BOOL finished) {
if (!_is_Anmotion) {
[self loopDrawLine];
}
_is_AnmotionFinished = YES;
}];
}
-(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds
{
CGFloat x,y,width,height;
x = rect.origin.x / readerViewBounds.size.width;
y = rect.origin.y / readerViewBounds.size.height;
width = rect.size.width / readerViewBounds.size.width;
height = rect.size.height / readerViewBounds.size.height;
return CGRectMake(x,y, width, height);
}
- (void)scanStart
{
_is_Anmotion = NO;
if (_is_AnmotionFinished) {
[self loopDrawLine];
}
[self.readerView start];
}
- (void)scanStop
{
_is_Anmotion = YES;
if (_is_AnmotionFinished) {
[self loopDrawLine];
}
[self.readerView stop];
}
@end
3.在VC中使用
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initScanReaderView];
}
//初始化扫描界面
- (void) initScanReaderView
{
//创建二维码扫描界面
_scanQRCodeView = [[NKScanQRCodeView alloc] initWithFrame:CGRectMake(0, 0, WIDTH_VIEW, HEIGHT_VIEW)];
[self.view addSubview:_scanQRCodeView];
_scanQRCodeView.vc = self;
//设置代理
_scanQRCodeView.readerView.readerDelegate = self;
//关闭闪光灯
_scanQRCodeView.readerView.torchMode = 0;
//关闭手动聚焦
_scanQRCodeView.readerView.allowsPinchZoom = NO;
[_scanQRCodeView scanStart];
}
//扫描结束后回调函数
-(void)readerView:(ZBarReaderView *)readerView didReadSymbols:(ZBarSymbolSet *)symbols fromImage:(UIImage *)image
{
//0.扫码完成后播放声音
[self playSound:@"NKQRCode.bundle/sound.caf"];
//1.停止扫描
[_scanQRCodeView scanStop];
//2.数据处理
NSString *parameterStr;
for (ZBarSymbol *symbol in symbols) {
NSLog(@"%@", symbol.data);
parameterStr = symbol.data;
break;
}
}
/** 播放音效文件 */
- (void)playSound:(NSString *)name {
// 获取音效
NSString *audioFile = [[NSBundle mainBundle] pathForResource:name ofType:nil];
NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
// 1、获得系统声音ID
SystemSoundID soundID = 0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
// 2、播放音频
AudioServicesPlaySystemSound(soundID); // 播放音效
}
/** 播放完成回调函数 */
void soundCompleteCallback(SystemSoundID soundID, void *clientData){
//SGQRCodeLog(@"播放完成...");
}