基于ZBard的二维码扫描

421 阅读7分钟

最近项目用到了二维码扫码的功能,在网上找了很多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(@"播放完成...");
}

github地址

点我