iOS7开始,不需要第三方也能进行二维码扫描了。

之前用过ZBar这个第三方包,后来iOS版本高了用不了,貌似我下的那个包只支持32位。

应该还有其他版本的支持,只是后来没用到就没去找了。

今天研究了一下系统自带的二维码扫描,扫描速度很快。

肚子饿,节约点时间直接上代码,因怎么用我也有注释了。大家根据需要看看响应的代码吧。

首先,导入

#import <AVFoundation/AVFoundation.h>

Ps:自己练习的时候,顺便复习了一下block传值和代理传值,在此代码也一起上了吧,不懂的可以看看,自己也权当做个笔记。

先附上扫描VC的.h代码

1. #import </span>"BaseVC.h"  
2. //该viewController是继承BaseVC(ViewController)创建<pre name="code" class="objc">

@protocol ScanDelegate <NSObject>//添加代理方法(默认情况下必须实现)- (void)setStringValue:(NSString *)stringValue;@optional//可选的方法@end@interface ScanVC : BaseVC//block传值@property (strong, nonatomic) void (^stringValue)(NSString *value);//代理传值@property (strong, nonatomic) id<ScanDelegate>delegate;@end

以下为.m的代码

1. #import "ScanVC.h"  
2. #import <AVFoundation/AVFoundation.h>  
3.   
4. @interface ScanVC ()<AVCaptureMetadataOutputObjectsDelegate>  
5.   
6. //**  
7. @property (strong, nonatomic) AVCaptureSession *captureSession;  
8. @property (strong, nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;  
9. @property (strong, nonatomic) AVCaptureMetadataOutput *captureMetadataOutput;  
10. @property (strong, nonatomic) UIView *viewPreview;//扫描窗口  
11.   
12. @end  
13.   
14. @implementation ScanVC  
15.   
16. - (void)viewDidLoad {  
17. super viewDidLoad];  
18.     /**  
19.      CaptureSession 这是个捕获会话,也就是说你可以用这个对象从输入设备捕获数据流。  
20.      AVCaptureVideoPreviewLayer 可以通过输出设备展示被捕获的数据流。  
21.      首先,应该判断当前设备是否有捕获数据流的设备。  
22.      */  
23. NSError *error;  
24. AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];  
25. AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];  
26.       
27. if (!input) {  
28. @"%@", [error localizedDescription]);  
29. else{  
30. //设置会话的输入设备  
31. if (!_captureSession) {  
32.  alloc] init];  
33.         }  
34.  addInput:input];  
35.           
36. //对应输出  
37. if (!_captureMetadataOutput) {  
38.  alloc] init];  
39.         }  
40.  addOutput:_captureMetadataOutput];  
41.           
42. //创建一个队列  
43.         dispatch_queue_t dispatchQueue;  
44. "myQueue",NULL);  
45.  setMetadataObjectsDelegate:self queue:dispatchQueue];  
46.  setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];//设置条码类型。更多类型底下补上  
47.           
48. //降捕获的数据流展现出来  
49.  alloc] initWithSession:_captureSession];  
50.  setVideoGravity:AVLayerVideoGravityResizeAspectFill];  
51.           
52. if (!_viewPreview) {  
53.  alloc]initWithFrame:CGRectMake(0, 0, 320, 320)];  
54. self.view addSubview:_viewPreview];  
55.         }          
56.  setFrame:_viewPreview.layer.bounds];  
57. .layer addSublayer:_videoPreviewLayer];  
58.           
59. //开始捕获  
60.  startRunning];  
61.     }  
62. }  
63.   
64. //获得的数据在 AVCaptureMetadataOutputObjectsDelegate 唯一定义的方法中  
65. - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{  
66. //判断是否有数据,是否是二维码数据  
67. if (metadataObjects != nil && [metadataObjects count] > 0) {  
68. AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];  
69. if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {  
70. //获得扫描的数据,并结束扫描  
71. self performSelectorOnMainThread:@selector(stopReading:)withObject:metadataObj.stringValue waitUntilDone:NO];  
72. //线程更新label的text值  
73. //            [_result performSelectorOnMainThread:@selector(setText:) withObject:metadataObj.stringValue waitUntilDone:NO];  
74. //block传值  
75. .stringValue);  
76. //代理传值  
77.  setStringValue:metadataObj.stringValue];  
78.         }  
79.     }  
80. }  
81.   
82. - (void)stopReading:(id)sender{  
83.  stopRunning];  
84.  nil;  
85.  removeFromSuperlayer];  
86.       
87. self.navigationController popViewControllerAnimated:YES];  
88. }  
89.   
90. - (void)didReceiveMemoryWarning {  
91. super didReceiveMemoryWarning];  
92. // Dispose of any resources that can be recreated.  
93. }  
94. @end

扫描类型补充:

AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeAztecCode,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeCode39Mod43Code

扫描的代码就这些了,以下为上一个VC接收block值和代理传过来的值:

头部记得导入代理<ScanDelegate>(自定义)

1. </pre><pre>

1. #pragma mark - 二维码扫描  
2. //扫描  
3. - (void)scan:(BaseBtn *)button{  
4.       
5. ScanVC *scanVC = [[ScanVC alloc]init];  
6.       
7. //block 方法  
8.  setStringValue:^(NSString *value) {  
9. @"%@",value);  
10.     }];  
11. //设置代理  
12. .delegate = self;  
13. self.navigationController pushViewController:scanVC animated:YES];  
14. }  
15. //代理传值  
16. - (void)setStringValue:(NSString *)stringValue{  
17.  performSelectorOnMainThread:@selector(setText:) withObject:stringValue waitUntilDone:NO];  
18. }

这段代码测试能获取到二维码的内容,一维码好像不能扫描,应该跟我的条码类型设置有关系。

找到比较多的条码类型,也在上边进行补充了,只是没有进行更多测试,有兴趣的可以自己去试试哈。

补充一下:

我遇到的问题:当前A_VC调用扫描的时候,结束后控件会卡住,不能进行任何操作。

我的解决方法:切换到另一个B_VC进行扫描,结束时返回当前A_VC控件就不会卡住,若要再次扫描再次进入B_VC即可。希望能帮到大家。