ios使用AVFoundation读取二维码的方法

2020-01-21 03:31:36丽君

ios,二维码,AVFoundation

在视图控制器中添加ToolBar、Flexible Space Bar Button Item、Bar Button Item、View,布局如下:

ios,二维码,AVFoundation

其中,各元素及作用:

    ToolBar:添加在控制器视图的最底部,其Bar Item标题为Start,具有双重作用,用于启动和停止扫描。 Flexible Space Bar Button Item:分别添加在Start的左右两侧,用于固定Start 的位置使其居中显示。 Bar Button Item:添加在导航栏的右侧,标题为Album,用于从相册选择二维码图片进行解析。 View:添加在控制器视图的中间,用于稍后设置扫描框。在这里使用自动布局固定宽高均为260,并且水平和垂直方向都是居中。

创建一个名为ScanView的新文件(FileNewFile…),它是UIView的子类。然后选中视图控制器中间添加的View,将该视图的类名更改为ScanView:

ios,二维码,AVFoundation

打开辅助编辑器,将storyboard中的元素连接到代码中:

ios,二维码,AVFoundation

注意,需要在ViewController.m文件中导入ScanView.h文件。

2.3 添加代码

2.3.1 扫描二维码

首先在ViewController.h文件中导入AVFoundation框架:


#import <AVFoundation/AVFoundation.h>

切换到ViewController.m文件,添加AVCaptureMetadataOutputObjectsDelegate协议,并在接口部分添加下面的属性:


@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>

// properties
@property (assign, nonatomic) BOOL isReading;
@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;

在viewDidLoad方法中添加下面代码:


- (void)viewDidLoad
{
 [super viewDidLoad];
 
 self.isReading = NO;
 self.captureSession = nil;
}

然后在实现部分添加startScanning方法和stopScanning方法及相关代码:


- (void)startScanning
{
 self.captureSession = [[AVCaptureSession alloc] init];
 
 // add input
 NSError *error;
 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error];
 if (!deviceInput) {
  NSLog(@"%@", [error localizedDescription]);
 }
 [self.captureSession addInput:deviceInput];
 
 // add output
 AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
 [self.captureSession addOutput:metadataOutput];
 
 // configure output
 dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
 [metadataOutput setMetadataObjectsDelegate:self queue:queue];
 [metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
 
 // configure previewLayer
 self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
 [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
 [self.previewLayer setFrame:self.view.bounds];
 [self.view.layer addSublayer:self.previewLayer];
 
 // start scanning
 [self.captureSession startRunning];
}

- (void)stopScanning
{
 [self.captureSession stopRunning];
 self.captureSession = nil;
 
 [self.previewLayer removeFromSuperlayer];
}