ios原生二維碼掃描

做iOS的二維碼掃描,有兩個(gè)第三方庫(kù)可以選擇,ZBar和ZXing。今天要介紹的是iOS7.0后AVFoundation框架提供的原生二維碼掃描。

首先需要添加AVFoundation.framework框架到你工程中build phase的"Link Binary With Libraries"之下,然后就可以開(kāi)始了。

一、做好準(zhǔn)備工作,搭建UI

UI效果如圖

IBOutlet、IBAction如下:

@property(weak, nonatomic) IBOutlet UIView *viewPreview;

@property(weak, nonatomic) IBOutlet UILabel *lblStatus;

@property(weak, nonatomic) IBOutlet UIButton *startBtn;

- (IBAction)startStopReading:(id)sender;

接下來(lái)就都是代碼的事情了

二、控制器ViewController.h

首先導(dǎo)入AVFoundation框架


1#import<AVFoundation/AVFoundation.h>

然后控制器實(shí)現(xiàn) AVCaptureMetadataOutputObjectsDelegate協(xié)議

1@interfaceViewController ()<AVCaptureMetadataOutputObjectsDelegate>

整體property如下:

@property(strong, nonatomic) UIView *boxView;

@property(nonatomic) BOOL isReading;

@property(strong, nonatomic) CALayer *scanLayer;

-(BOOL)startReading;

-(void)stopReading;

//捕捉會(huì)話

1@property (nonatomic, strong) AVCaptureSession *captureSession;

//展示layer

1@property(nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;

然后在ViewDidLoad方法中初始化

- (void)viewDidLoad {

??[superviewDidLoad];


??_captureSession = nil;

???_isReading = NO;


}

接下來(lái)實(shí)現(xiàn)startReading方法(這可就是重點(diǎn)咯)

- (BOOL)startReading {

?NSError *error;

?//1.初始化捕捉設(shè)備(AVCaptureDevice),類(lèi)型為AVMediaTypeVideo

?AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

?//2.用captureDevice創(chuàng)建輸入流

?AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];

?if(!input) {

??NSLog(@"%@", [error localizedDescription]);

??returnNO;

?}

?//3.創(chuàng)建媒體數(shù)據(jù)輸出流

?AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];

?//4.實(shí)例化捕捉會(huì)話

?_captureSession = [[AVCaptureSession alloc] init];

?//4.1.將輸入流添加到會(huì)話

?[_captureSession addInput:input];

?//4.2.將媒體輸出流添加到會(huì)話中

?[_captureSession addOutput:captureMetadataOutput];

?//5.創(chuàng)建串行隊(duì)列,并加媒體輸出流添加到隊(duì)列當(dāng)中

?dispatch_queue_t dispatchQueue;

?dispatchQueue = dispatch_queue_create("myQueue", NULL);

?//5.1.設(shè)置代理

?[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];

?//5.2.設(shè)置輸出媒體數(shù)據(jù)類(lèi)型為QRCode

?[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];

?//6.實(shí)例化預(yù)覽圖層

?_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];

?//7.設(shè)置預(yù)覽圖層填充方式

?[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

?//8.設(shè)置圖層的frame

?[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];

?//9.將圖層添加到預(yù)覽view的圖層上

?[_viewPreview.layer addSublayer:_videoPreviewLayer];

?//10.設(shè)置掃描范圍

?captureMetadataOutput.rectOfInterest = CGRectMake(0.2f, 0.2f, 0.8f, 0.8f);

?//10.1.掃描框

?_boxView = [[UIView alloc] initWithFrame:CGRectMake(_viewPreview.bounds.size.width * 0.2f, _viewPreview.bounds.size.height * 0.2f, _viewPreview.bounds.size.width - _viewPreview.bounds.size.width * 0.4f, _viewPreview.bounds.size.height - _viewPreview.bounds.size.height * 0.4f)];

?_boxView.layer.borderColor = [UIColor greenColor].CGColor;

?_boxView.layer.borderWidth = 1.0f;

?[_viewPreview addSubview:_boxView];

?//10.2.掃描線

?_scanLayer = [[CALayer alloc] init];

?_scanLayer.frame = CGRectMake(0, 0, _boxView.bounds.size.width, 1);

?_scanLayer.backgroundColor = [UIColor brownColor].CGColor;

?[_boxView.layer addSublayer:_scanLayer];

?NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(moveScanLayer:) userInfo:nil repeats:YES];

?[timer fire];


?//10.開(kāi)始掃描

?[_captureSession startRunning];

?returnYES;

}

實(shí)現(xiàn)AVCaptureMetadataOutputObjectsDelegate協(xié)議方法

#pragma mark - AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection

{

?//判斷是否有數(shù)據(jù)

?if(metadataObjects != nil && [metadataObjects count] > 0) {

??AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];

??//判斷回傳的數(shù)據(jù)類(lèi)型

??if([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {

???[_lblStatus performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];

???[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];

???_isReading = NO;

??}

?}

}

實(shí)現(xiàn)計(jì)時(shí)器方法moveScanLayer:(NSTimer *)timer

- (void)moveScanLayer:(NSTimer *)timer

{

?CGRect frame = _scanLayer.frame;

?if(_boxView.frame.size.height < _scanLayer.frame.origin.y) {

??frame.origin.y = 0;

??_scanLayer.frame = frame;

?}else{

??frame.origin.y += 5;

??[UIView animateWithDuration:0.1animations:^{

???_scanLayer.frame = frame;

??}];

?}

}

實(shí)現(xiàn)開(kāi)始和停止方法

- (IBAction)startStopReading:(id)sender {

??if(!_isReading) {

???if([self startReading]) {

????[_startBtn setTitle:@"Stop"forState:UIControlStateNormal];

????[_lblStatus setText:@"Scanning for QR Code"];

???}

??}

??else{

???[self stopReading];

???[_startBtn setTitle:@"Start!"forState:UIControlStateNormal];

??}

??_isReading = !_isReading;

}

-(void)stopReading{

?[_captureSession stopRunning];

?_captureSession = nil;

?[_scanLayer removeFromSuperlayer];

?[_videoPreviewLayer removeFromSuperlayer];

}

以上內(nèi)容就是本文給大家介紹ios原生二維碼掃描的全部?jī)?nèi)容,希望大家喜歡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容