#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "WebViewController.h" //创建webview
static const char *kScanQRCodeQueueName = "ScanQRCodeQueue"; //自定义线程的名字
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (weak, nonatomic) IBOutlet UIView *sanFrameView; //扫描窗口
@property (weak, nonatomic) IBOutlet UIButton *lightButton; //灯按钮
@property (weak, nonatomic) IBOutlet UIButton *captureButton; //开始扫描按钮
@property (nonatomic) AVCaptureSession *captureSession; //会话,用于添加输入流和输出流
@property (nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer; //输出对象
@property (nonatomic) BOOL lastResult;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/**
基本逻辑:
扫描二维码,将扫描到的网址二维码直接扔到webview中进行显示
*/
[self.lightButton setTitle:@"打开照明" forState:UIControlStateNormal]; //设置灯按钮的初始状态
[self.captureButton setTitle:@"开始" forState:UIControlStateNormal]; //设置扫描按钮的状态
self.lastResult = YES; //初始化判断
}
#pragma mark **************扫描部分 begin*****************
#pragma mark 扫描按钮点击事件
- (IBAction)captureButtonClick:(UIButton *)sender {
if ([self.captureButton.titleLabel.text isEqualToString:@"开始"]) {
[self startReading];
} else {
[self stopReading];
}
}
#pragma mrak 开始扫描方法
- (BOOL)startReading {
[self.captureButton setTitle:@"停止" forState:UIControlStateNormal];
#pragma mark 获取设备实例
NSError *error;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
#pragma mark 创建会话
self.captureSession = [[AVCaptureSession alloc] init];
#pragma mark 创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
//如果设备输入流不存在,直接返回
if (!input) {
NSLog(@"%@",[error localizedDescription]);
return NO;
}
[self.captureSession addInput:input]; //会话添加输入流
#pragma mark 创建输出流
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:output]; //会话添加输出流
#pragma mark 添加输出代理,用于接收输出的数据
dispatch_queue_t dispatchQueue = dispatch_queue_create(kScanQRCodeQueueName, NULL);
[output setMetadataObjectsDelegate:self queue:dispatchQueue];
#pragma mark 设置输出的元数据类型 AVMetadataObjectTypeQRCode 二维码类型
[output setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
#pragma mark 根据会话设置创建输出对象
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.videoPreviewLayer.frame = self.sanFrameView.layer.bounds;
[self.sanFrameView.layer addSublayer:self.videoPreviewLayer];
//设置完成,开始会话
[self.captureSession startRunning];
return YES;
}
#pragma mark 停止扫描方法
- (void)stopReading {
[self.captureButton setTitle:@"开始" forState:UIControlStateNormal];
[self.captureSession stopRunning];
self.captureSession = nil;
}
#pragma mark 输出流代理方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
if (metadataObjects != nil && metadataObjects.count) {
AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0];
NSString *result;
if ([[metadataObject type] isEqualToString:AVMetadataObjectTypeQRCode]) {
result = metadataObject.stringValue;
} else {
NSLog(@"不是二维码");
}
//将结果带到主线程,进行确认
[self performSelectorOnMainThread:@selector(outputResult:) withObject:result waitUntilDone:NO];
}
}
#pragma mark 接收扫描的内容
- (void)outputResult:(NSString *)result {
[self stopReading]; //得到结果,结束读取
if (!_lastResult) {
return;
}
NSLog(@"result = %@",result);
_lastResult = NO;
#pragma mark 创建一个警告controller
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"二维码扫描" message:result preferredStyle:UIAlertControllerStyleAlert];
#pragma mark 创建取消按钮
UIAlertAction *concelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
#pragma mark 添加一个确认按钮 实现按钮的点击事件
UIAlertAction *getAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
WebViewController *webview = [[WebViewController alloc] init];
webview.url = result;
[self.navigationController pushViewController:webview animated:YES];
NSLog(@"将内容推出去");
}];
[alertController addAction:concelAction]; //添加取消按钮
[alertController addAction:getAction]; //添加确认按钮
#pragma mark 模态视图出现
[self presentViewController:alertController animated:YES completion:nil];
_lastResult = YES;
}
#pragma mark **************扫描部分 end*******************
#pragma mark **************灯 begin*******************
#pragma mark 灯按钮的点击事件
- (IBAction)lightButtonClick:(UIButton *)sender {
if ([self.lightButton.titleLabel.text isEqualToString:@"打开照明"]) {
[self systemLightSwith:YES];
} else {
[self systemLightSwith:NO];
}
}
#pragma mark 灯触发事件
- (void)systemLightSwith:(BOOL)open {
//改变按钮的状态
if (open) {
[self.lightButton setTitle:@"关闭" forState:UIControlStateNormal];
} else {
[self.lightButton setTitle:@"打开照明" forState:UIControlStateNormal];
}
//获取当前的设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//如果存在设备,设置
if ([device hasTorch]) {
[device lockForConfiguration:nil];
if (open) { //打开
[device setTorchMode:AVCaptureTorchModeOn];
} else { //关闭
[device setTorchMode:AVCaptureTorchModeOff];
}
[device unlockForConfiguration];
} else {
NSLog(@"不存在照明设备");
}
}
#pragma mark **************灯 end*******************
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end