做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing。今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描。

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

  一、做好准备工作,搭建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;

  接下来就都是代码的事情了

  二、控制器ViewController.h

  首先导入AVFoundation框架

#import <AVFoundation/AVFoundation.h>

  然后控制器实现AVCaptureMetadataOutputObjectsDelegate协议

@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>

  整体property如下:

@property (strong, nonatomic) UIView *boxView;
@property (nonatomic) BOOL isReading;
@property (strong, nonatomic) CALayer *scanLayer; -(BOOL)startReading;
-(void)stopReading; //捕捉会话
@property (nonatomic, strong) AVCaptureSession *captureSession;
//展示layer
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;

  然后在ViewDidLoad方法中初始化

- (void)viewDidLoad {
[super viewDidLoad]; _captureSession = nil;
_isReading = NO; }

  接下来实现startReading方法(这可就是重点咯)

- (BOOL)startReading {
NSError *error; //1.初始化捕捉设备(AVCaptureDevice),类型为AVMediaTypeVideo
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //2.用captureDevice创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
} //3.创建媒体数据输出流
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init]; //4.实例化捕捉会话
_captureSession = [[AVCaptureSession alloc] init]; //4.1.将输入流添加到会话
[_captureSession addInput:input]; //4.2.将媒体输出流添加到会话中
[_captureSession addOutput:captureMetadataOutput]; //5.创建串行队列,并加媒体输出流添加到队列当中
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
//5.1.设置代理
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; //5.2.设置输出媒体数据类型为QRCode
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]]; //6.实例化预览图层
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession]; //7.设置预览图层填充方式
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; //8.设置图层的frame
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds]; //9.将图层添加到预览view的图层上
[_viewPreview.layer addSublayer:_videoPreviewLayer]; //10.设置扫描范围
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(, , _boxView.bounds.size.width, );
_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.开始扫描
[_captureSession startRunning];
return YES;
}

  实现AVCaptureMetadataOutputObjectsDelegate协议方法

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

  实现计时器方法moveScanLayer:(NSTimer *)timer

- (void)moveScanLayer:(NSTimer *)timer
{
CGRect frame = _scanLayer.frame;
if (_boxView.frame.size.height < _scanLayer.frame.origin.y) {
frame.origin.y = ;
_scanLayer.frame = frame;
}else{ frame.origin.y += ; [UIView animateWithDuration:0.1 animations:^{
_scanLayer.frame = frame;
}];
}
}

  实现开始和停止方法

- (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];
}

  大功告成

  示例源码地址:https://github.com/WuKongCoo1/QRCodeReader

    

iOS:原生二维码扫描的更多相关文章

  1. iOS 原生二维码扫描和生成

    代码地址如下:http://www.demodashi.com/demo/12551.html 一.效果预览: 功能描述:WSLNativeScanTool是在利用原生API的条件下封装的二维码扫描工 ...

  2. iOS 原生二维码扫描(可限制扫描区域)

    篇文章的主要原因不是展示如何使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了 ...

  3. 【转】 iOS 原生二维码扫描(可限制扫描区域)

    在用 AVFoundation 完成扫码后,遇到2个问题: 1,如何限制扫描范围? 2.条形码如何扫描? 一位朋友的文章帮助了我,特地转来,可以帮到有需要的朋友. 原文:http://blog.csd ...

  4. iOS 原生二维码扫描,带扫描框和扫描过程动画

    在代码中使用了相对布局框架Masonry 准备两张图片,一张是扫描边框,一张是扫描时的细线分别命名 scanFrame.png和scanLine.png并提前放入工程 导入相对布局头文件 #defin ...

  5. iOS开发-二维码扫描和应用跳转

    iOS开发-二维码扫描和应用跳转   序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  6. Firemonkey 原生二维码扫描优化

    之前用了ZXing的Delphi版本,运行自带的例子,速度非常慢,与安卓版本的相比查了很多,因此打算使用集成jar的方法,但是总觉得美中不足. 经过一番研究,基本上解决了问题. 主要有两方面的优化: ...

  7. iOS 系统二维码扫描(可限制扫描区域)

    使用 AVFoundation系统库来进行二维码扫描并且限制扫描二维码的范围.(因为默认的是全屏扫描) -(void)beginCode { //1.摄像头设备 AVCaptureDevice *de ...

  8. ios7 苹果原生二维码扫描(和微信类似)

    在ios7苹果推出了二维码扫描,以前想要做二维码扫描,只能通过第三方ZBar与ZXing. ZBar在扫描的灵敏度上,和内存的使用上相对于ZXing上都是较优的,但是对于 “圆角二维码” 的扫描确很困 ...

  9. ipad开发:二维码扫描,摄像头旋转角度问题解决办法

    之前一直是在手机上开发,用系统原生二维码扫描功能,一点问题都没有,但是在ipad上,用户是横屏操作的,虽然界面旋转了,是横屏的,但是摄像头里显示的依然是竖屏效果,也就是说从摄像头里看到的和人眼看到的内 ...

随机推荐

  1. eclipse 快捷方式大全

    Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当 ...

  2. Telnet RFC

    http://tools.ietf.org/html/rfc857 http://www.faqs.org/rfcs/rfc854.html 不错: http://blog.csdn.net/chao ...

  3. mini KMS Activator v1.3破解激活microsoft Office 2010 RTM

    利用mini KMS Activator v1.3破解激活microsoft Office 2010 RTM方法,只是为体验office而做测试使用的哦...大家觉得好就自觉购买正版去... 使用步骤 ...

  4. [Leetcode][Python]36: Valid Sudoku

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 36: Valid Sudokuhttps://oj.leetcode.com ...

  5. mongodb remove删除文档的用法

    在看<mongoDB权威指南>中,在删除文档时,出现问题: 书中介绍:采用db.foo.remove()命令则可以删除foo集合中所有的文档,但是在执行该命令时,shell客户端却报错. ...

  6. Paxos算法小结

    转自不正直的绅士,因百度空间迁移,无法注明出处,我从其google搜索引擎中的cache进行的copy. 不正直的绅士 是跟我一起工作过的非常有才的一个青年才俊. Paxos的使用非常广泛.sanlo ...

  7. _.each的用法2

    有这样一个需求:一个对象数组: 内容如下: {[ {id:"ssss",position:"4"}, {id:"ssss",position ...

  8. 学习使用crosswalk

    1.创建一个工程,最好使用Swift语言,或者也可以叫做雨燕语言,名字很好听吧,功能也是很强大的.言归正传,创建好工程后,需要用CocoaPod工具,不懂的童鞋自行google吧. 根据CrossWa ...

  9. WebStorm 7.0 注冊码

    经測试 WebStorm 6 7均能够使用例如以下注冊码,简直就是神key啊! WebStorm 6.0 7.0 注冊码 User Name: EMBRACE   License Key: ===== ...

  10. SQL学习之学会使用子查询

    1.SELECT语句是SQL的查询.我之前的随笔中所用的SELECT语句都是简单的查询,即从单个数据库表中检索数据的单条SELECT语句. 查询:任何SQL语句都是查询,但此术语一般指SELECT语句 ...