在iOS7以后,AVFoundation中就添加了QR码部分,QR是指快速反应。
详细代码,请戳这里
首先,要引入
#import <AVFoundation/AVFoundation.h>
1.原生扫描用到的几个类
@property (strong,nonatomic)AVCaptureDevice * device;
@property (strong,nonatomic)AVCaptureDeviceInput * input;
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
@property (strong,nonatomic)AVCaptureSession * session;
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;
2.实现
- (void)startScan
{
// 1.判断是否能够将输入添加到会话中
if (![self.session canAddInput:self.deviceInput]) {
return;
}
// 2.判断是否能够将输出添加到会话中
if (![self.session canAddOutput:self.output]) {
return;
}
// 3.将输入和输出都添加到会话中
[self.session addInput:self.deviceInput];
[self.session addOutput:self.output];
// 4.设置输出能够解析的数据类型
// 注意: 设置能够解析的数据类型, 一定要在输出对象添加到会员之后设置, 否则会报错
self.output.metadataObjectTypes = self.output.availableMetadataObjectTypes;
[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 如果想实现只扫描一张图片, 那么系统自带的二维码扫描是不支持的
// 只能设置让二维码只有出现在某一块区域才去扫描
// self.output.rectOfInterest = CGRectMake(0.0, 0.0, 1, 1);
// 设置二维码区域参考http://www.tuicool.com/articles/6jUjmur
//扫描区域和正常的坐标系不太一样,是从右上角开始的,而且是比例,不是传统的坐标值
CGFloat ScreenHigh = [UIScreen mainScreen].bounds.size.height;
CGFloat ScreenWidth = [UIScreen mainScreen].bounds.size.width;
[self.output setRectOfInterest : CGRectMake ((self.view.center.y - self.containerViewWidthCon.constant / 2)/ ScreenHigh , (ScreenWidth - self.containerViewWidthCon.constant)/2 / ScreenWidth,self.containerViewWidthCon.constant / ScreenHigh, self.containerViewWidthCon.constant / ScreenWidth)];
// 5.添加预览图层
[self.view.layer insertSublayer:self.previewLayer atIndex:0];
// 6.告诉session开始扫描
[self.session startRunning];
}
3.设置成功回调代理
/**
* 当从二维码中获取到信息时,就会调用下面的方法
*
* @param captureOutput 输出对象
* @param metadataObjects 信息
* @param connection v
*/
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count == 0 || metadataObjects == nil) {
return;
}
// 1.获取扫描到的数据
// 注意: 要使用stringValue
//判断是否有数据
if (metadataObjects != nil && [metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects lastObject];
//判断回传的数据类型
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode] && [metadataObj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
// 扫描结果
NSString *result = [metadataObjects.lastObject stringValue];
// 停止扫描
[self stopScan];
if (_completionBlock) {
[self.beepPlayer play];
_completionBlock(result);
}
if (self.delegate && [self.delegate respondsToSelector:@selector(reader:didScanResult:)]) {
[self.delegate reader:self didScanResult:result];
}
return;
}
}
}