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

其中,各元素及作用:
-
ToolBar:添加在控制器视图的最底部,其Bar Item标题为Start,具有双重作用,用于启动和停止扫描。
Flexible Space Bar Button Item:分别添加在Start的左右两侧,用于固定Start 的位置使其居中显示。
Bar Button Item:添加在导航栏的右侧,标题为Album,用于从相册选择二维码图片进行解析。
View:添加在控制器视图的中间,用于稍后设置扫描框。在这里使用自动布局固定宽高均为260,并且水平和垂直方向都是居中。
创建一个名为ScanView的新文件(FileNewFile…),它是UIView的子类。然后选中视图控制器中间添加的View,将该视图的类名更改为ScanView:

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

注意,需要在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];
}










