iOS7开始,不需要第三方也能进行二维码扫描了。
之前用过ZBar这个第三方包,后来iOS版本高了用不了,貌似我下的那个包只支持32位。
应该还有其他版本的支持,只是后来没用到就没去找了。
今天研究了一下系统自带的二维码扫描,扫描速度很快。
肚子饿,节约点时间直接上代码,因怎么用我也有注释了。大家根据需要看看响应的代码吧。
首先,导入
#import <AVFoundation/AVFoundation.h>
Ps:自己练习的时候,顺便复习了一下block传值和代理传值,在此代码也一起上了吧,不懂的可以看看,自己也权当做个笔记。
先附上扫描VC的.h代码
- #import </span>"BaseVC.h"
- //该viewController是继承BaseVC(ViewController)创建<pre name="code" class="objc">
以下为.m的代码
- #import "ScanVC.h"
- #import <AVFoundation/AVFoundation.h>
- @interface ScanVC ()<AVCaptureMetadataOutputObjectsDelegate>
- //**
- @property (strong, nonatomic) AVCaptureSession *captureSession;
- @property (strong, nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;
- @property (strong, nonatomic) AVCaptureMetadataOutput *captureMetadataOutput;
- @property (strong, nonatomic) UIView *viewPreview;//扫描窗口
- @end
- @implementation ScanVC
- - (void)viewDidLoad {
- [super viewDidLoad];
- /**
- CaptureSession 这是个捕获会话,也就是说你可以用这个对象从输入设备捕获数据流。
- AVCaptureVideoPreviewLayer 可以通过输出设备展示被捕获的数据流。
- 首先,应该判断当前设备是否有捕获数据流的设备。
- */
- NSError *error;
- AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
- AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
- if (!input) {
- NSLog(@"%@", [error localizedDescription]);
- }else{
- //设置会话的输入设备
- if (!_captureSession) {
- _captureSession = [[AVCaptureSession alloc] init];
- }
- [_captureSession addInput:input];
- //对应输出
- if (!_captureMetadataOutput) {
- _captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
- }
- [_captureSession addOutput:_captureMetadataOutput];
- //创建一个队列
- dispatch_queue_t dispatchQueue;
- dispatchQueue = dispatch_queue_create("myQueue",NULL);
- [_captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
- [_captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];//设置条码类型。更多类型底下补上
- //降捕获的数据流展现出来
- _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
- [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
- if (!_viewPreview) {
- _viewPreview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 320)];
- [self.view addSubview:_viewPreview];
- }
- [_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
- [_viewPreview.layer addSublayer:_videoPreviewLayer];
- //开始捕获
- [_captureSession startRunning];
- }
- }
- //获得的数据在 AVCaptureMetadataOutputObjectsDelegate 唯一定义的方法中
- - (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 performSelectorOnMainThread:@selector(stopReading:)withObject:metadataObj.stringValue waitUntilDone:NO];
- //线程更新label的text值
- // [_result performSelectorOnMainThread:@selector(setText:) withObject:metadataObj.stringValue waitUntilDone:NO];
- //block传值
- _stringValue(metadataObj.stringValue);
- //代理传值
- [_delegate setStringValue:metadataObj.stringValue];
- }
- }
- }
- - (void)stopReading:(id)sender{
- [_captureSession stopRunning];
- _captureSession = nil;
- [_videoPreviewLayer removeFromSuperlayer];
- [self.navigationController popViewControllerAnimated:YES];
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- @end
扫描类型补充:
AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeAztecCode,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeCode39Mod43Code
头部记得导入代理<ScanDelegate>(自定义)
- </pre><pre>
- #pragma mark - 二维码扫描
- //扫描
- - (void)scan:(BaseBtn *)button{
- ScanVC *scanVC = [[ScanVC alloc]init];
- //block 方法
- [scanVC setStringValue:^(NSString *value) {
- NSLog(@"%@",value);
- }];
- //设置代理
- scanVC.delegate = self;
- [self.navigationController pushViewController:scanVC animated:YES];
- }
- //代理传值
- - (void)setStringValue:(NSString *)stringValue{
- [_result performSelectorOnMainThread:@selector(setText:) withObject:stringValue waitUntilDone:NO];
- }
这段代码测试能获取到二维码的内容,一维码好像不能扫描,应该跟我的条码类型设置有关系。
找到比较多的条码类型,也在上边进行补充了,只是没有进行更多测试,有兴趣的可以自己去试试哈。
补充一下:
我遇到的问题:当前A_VC调用扫描的时候,结束后控件会卡住,不能进行任何操作。
我的解决方法:切换到另一个B_VC进行扫描,结束时返回当前A_VC控件就不会卡住,若要再次扫描再次进入B_VC即可。
希望能帮到大家。