iOS学习笔记技术类iOS Developer

iOS开发-五步完成二维码扫描

2016-06-23  本文已影响3404人  for_in

由于各种第三方二维码扫描组件都不支持64位,并且已经停止更新很久了,所以现在一般都使用AVFoundation去实现二维码/条码的扫描。

基本所有app的扫一扫要跳转一个新的界面去,所以最好新建一个控制器ScanViewController

第一步

导入AVFoundation框架和遵守协议<AVCaptureMetadataOutputObjectsDelegate>

#import <AVFoundation/AVFoundation.h>
@interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>

第二步

初始化捕捉设备AVCaptureDevice

AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

创建输入

AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
    if (!input) {
        NSLog(@"%@", [error localizedDescription]);
        return;
    }

创建输出

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

创建一个会话,并添加输入和输出

self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession addInput:input];
[self.captureSession addOutput:captureMetadataOutput];

设置输出数据的类型,AVMetadataObjectTypeQRCode为二维码类型,其他类型可以到这个头文件AVMetadataObject.h里面查看

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

第三步

创建图层,摄像头捕捉到的画面都会在这个图层显示

self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];

设置图层填充方式

[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

设置图层的frame

[self.videoPreviewLayer setFrame:self.view.layer.bounds];

将图层添加到预览view的图层上

[self.view.layer addSublayer:self.videoPreviewLayer];

第四步

创建一个串行队列,并设置代理

dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];

第五步

设置扫码范围

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

开始扫码

[self.captureSession startRunning];

实现代理方法获取扫描到的数据

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    //判断是否有数据
    if (metadataObjects != nil && [metadataObjects count] > 0) {
        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
        //判断回传的数据类型
        if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
            self.license = [metadataObj stringValue];
            [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
        }
    }
}

完整的Demo在这里https://github.com/HuangJiayong/HJYScanCode

上一篇下一篇

猜你喜欢

热点阅读