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即可。希望能帮到大家。