# 扫描二维码
# 扫描二维码
### 以下是.m文件的完整代码
#import "ScanViewController.h"
#define UIColorWithRGB(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
@interface ScanViewController ()@property (strong, nonatomic) UIView *boxView;/**<扫描框*/
@property (nonatomic) BOOL isReading; /**<正在扫描*/
@property (strong, nonatomic) CALayer *scanLayer; /**<扫描框类容的图层*/
@property (nonatomic, strong) AVCaptureSession *captureSession;/**<捕捉会话*/
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;/**<展示layer*/
@property (weak, nonatomic) UIView *viewPreview;
@property (weak, nonatomic) UILabel *lblStatus;
@property(weak,nonatomic) NSTimer * timer;
@end
@implementation ScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
_isReading = NO;
_captureSession = nil ;
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
UIView * viewPreview = [[UIView alloc]init];
[self.view addSubview:viewPreview];
self.viewPreview = viewPreview;
}
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.viewPreview.frame = self.view.bounds;
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self startReading];
NSLog(@"frame:%@",NSStringFromCGRect(self.view.frame));
}
//开始扫描
-(BOOL)startReading{
// 1. 摄像头设备
AVCaptureDevice * captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//2.用captureDeviece创建输入流
// 因为模拟器是没有摄像头的,因此在此做一个判断
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (error) {
NSLog(@"没有摄像头-%@", error.localizedDescription);
// return;
}
//3.创建媒体数据输出流
AVCaptureMetadataOutput * captureMetadataOutput = [[AVCaptureMetadataOutput alloc]init];
//4.实例化捕捉会话
_captureSession = [[AVCaptureSession alloc]init];
[_captureSession addInput:input];
[_captureSession addOutput:captureMetadataOutput];
dispatch_queue_t dispatchQueue = dispatch_queue_create("queue", NULL);
// 4. 拍摄会话(设置输出代理)
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
// 4.1 设置输出的格式(媒体的数据类型)
// 提示:一定要先设置会话的输出为output之后,再指定输出的元数据类型!
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
//实例化预览图层(用来让用户能够看到扫描情况)
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
// 5.1 设置preview图层的属性(预览图层的填充模式)
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
// 5.2 设置preview图层的大小(图层的frame)
[_videoPreviewLayer setFrame:self.viewPreview.bounds];
// 5.3 将图层添加到视图的图层(添加图层在展示view上)
[self.viewPreview.layer addSublayer:_videoPreviewLayer];
captureMetadataOutput.rectOfInterest = CGRectMake (((self.view.bounds.size.height - 200 )/ 2 )/ self.view.bounds.size.height ,(( self.view.bounds.size.width - 200 )/ 2 )/ self.view.bounds.size.width , 200 / self.view.bounds.size.height , 200 / self.view.bounds.size.width);
//扫描框
UIView * boxView = [[UIView alloc] initWithFrame:CGRectMake(_viewPreview.bounds.size.width/2 -100, _viewPreview.bounds.size.height/2 - 100,200 ,200) ];
self.boxView.backgroundColor = [UIColor clearColor];
self.boxView = boxView;
self.boxView.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.boxView.layer.borderWidth = 2.0;
[_viewPreview addSubview:self.boxView];
//扫描线条
_scanLayer = [[CALayer alloc]init];
_scanLayer.frame = CGRectMake(0, 0, self.boxView.bounds.size.width, 2);
_scanLayer.shadowOffset = CGSizeMake(0, 5); //设置阴影的偏移量
_scanLayer.shadowRadius = 10.0; //设置阴影的半径
_scanLayer.shadowColor = [UIColor purpleColor].CGColor; //设置阴影的颜色为紫色
_scanLayer.shadowOpacity = 0.8; //设置阴影的不透明度
_scanLayer.backgroundColor = [UIColor colorWithRed:0.737 green:0.341 blue:0.965 alpha:1.000].CGColor;
[self.boxView.layer addSublayer:_scanLayer];
//设置扫描区域顶部透明图层
UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.viewPreview.bounds.size.width,self.boxView.frame.origin.y )];
topView.backgroundColor = [UIColor blackColor];
topView.alpha = 0.4;
[self.viewPreview addSubview:topView];
//设置扫描区域底部透明图层
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.boxView.frame), self.viewPreview.frame.size.width,self.viewPreview.bounds.size.height- CGRectGetMaxY(self.boxView.frame))];
bottomView.backgroundColor = [UIColor blackColor];
bottomView.alpha = 0.4;
[self.viewPreview addSubview:bottomView];
//设置扫描区域左部透明图层
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, self.boxView.frame.origin.y, boxView.frame.origin.x,self.boxView.frame.size.height)];
leftView.backgroundColor = [UIColor blackColor];
leftView.alpha = 0.4;
[self.viewPreview addSubview:leftView];
//设置扫描区域右部透明图层
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.boxView.frame), self.boxView.frame.origin.y, self.viewPreview.bounds.size.width-CGRectGetMaxX(self.boxView.frame), self.boxView.frame.size.height)];
rightView.backgroundColor = [UIColor blackColor];
rightView.alpha = 0.4;
[self.viewPreview addSubview:rightView];
//扫描线条跳动定时器
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(moveScanLayer:) userInfo:nil repeats:YES];
[timer fire];
self.timer = timer;
// 6. 启动会话(开始扫描)
[_captureSession startRunning];
return YES;
}
-(void)moveScanLayer:(NSTimer * )timer{
CGRect frame = _scanLayer.frame;
if (_boxView.height <= _scanLayer.frame.origin.y) {
frame.origin.y = 0;
_scanLayer.frame = frame;
}else{
frame.origin.y += 5;
[UIView animateWithDuration:0.1 animations:^{
_scanLayer.frame = frame;
}];
}
}
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
// 此方法是在识别到QRCode,并且完成转换
// 如果QRCode的内容越大,转换需要的时间就越长
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects&&metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject * metadataObj = [metadataObjects objectAtIndex:0];
if ([[metadataObj type]isEqualToString:AVMetadataObjectTypeQRCode]) {
NSLog(@"Arrary:%@------",metadataObj.corners);
NSLog(@"Arrary:%@++++++",metadataObj.stringValue);
/**
* 这里需要判断 stringValue 里面包含的信息 比如判断优惠券的有效期 需要截取字符串 下面不具有实际意义
*/
if(!metadataObj.stringValue){//实际判断有效性条件不是这样写的
dispatch_sync(dispatch_get_main_queue(), ^{
//添加数据成功了
[NSThread sleepForTimeInterval:1];
[self stopReading];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(self.boxView.center.x-150, self.boxView.center.y-125, 300, 250)];
[self.viewPreview addSubview:view];
view.backgroundColor = [UIColor whiteColor];
UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"设置密码"]];
imageView.center=CGPointMake(150, 82.5);
[view addSubview:imageView];
UILabel * label = [[UILabel alloc]init];
label.text = @"现金券已经过期";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = UIColorWithRGB(102, 102, 102);
label.font = [UIFont systemFontOfSize:18];
label.frame = CGRectMake(0, 0, 200,18);
label.center =CGPointMake(150, 173.5);
[view addSubview:label];
UIView * line = [[UIView alloc]initWithFrame:CGRectMake(0, 206, 300, 0.5)];
line.backgroundColor = [UIColor grayColor];
[view addSubview:line];
UIButton *tureButton = [UIButton buttonWithType:UIButtonTypeCustom];
tureButton.frame = CGRectMake(0, 206.5, 300, 43.5);
tureButton.tag = 1;
[tureButton setTitle:@"确认" forState:UIControlStateNormal];
[tureButton setTitle:@"确认" forState:UIControlStateHighlighted];
tureButton.titleLabel.font = [UIFont systemFontOfSize:18];
tureButton.titleLabel.textColor = [UIColor purpleColor];
[view addSubview:tureButton];
});
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
//添加数据成功了
[NSThread sleepForTimeInterval:1];
[self stopReading];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(self.boxView.center.x-150, self.boxView.center.y-125, 300, 250)];
[self.viewPreview addSubview:view];
view.backgroundColor = [UIColor whiteColor];
UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"添加成功"]];
imageView.center=CGPointMake(150, 82.5);
[view addSubview:imageView];
UILabel * label = [[UILabel alloc]init];
label.text = @"现金券有效";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = UIColorWithRGB(102, 102, 102);
label.font = [UIFont systemFontOfSize:18];
label.frame = CGRectMake(0, 0, 200,18);
label.center = CGPointMake(150, 173.5);
[view addSubview:label];
UIView * line = [[UIView alloc]initWithFrame:CGRectMake(0, 206, 300, 0.5)];
line.backgroundColor = [UIColor grayColor];
[view addSubview:line];
UIButton *backButton = [[UIButton alloc] init];
backButton.frame = CGRectMake(0, 200.5, 150, 43.5);
backButton.tag = 2;
[backButton setTitle:@"返回" forState:UIControlStateNormal];
[backButton setTitle:@"返回" forState:UIControlStateHighlighted];
backButton.titleLabel.font = [UIFont systemFontOfSize:18];
backButton.titleLabel.textColor = [UIColor blackColor];
backButton.backgroundColor = UIColorWithRGB(102, 102, 102);
[view addSubview:backButton];
UIButton *cheackButton = [[UIButton alloc] init];
cheackButton.frame = CGRectMake(150, 200.5, 150, 43.5);
cheackButton.tag = 3;
[cheackButton setTitle:@"马上查看" forState:UIControlStateNormal];
[cheackButton setTitle:@"马上查看" forState:UIControlStateHighlighted];
cheackButton.titleLabel.font = [UIFont systemFontOfSize:18];
cheackButton.titleLabel.textColor = [UIColor colorWithRed:0.737 green:0.341 blue:0.965 alpha:1.000];
cheackButton.backgroundColor = UIColorWithRGB(102, 102, 102);
[view addSubview:cheackButton];
});
}
}
}
}
-(void)stopReading{
// 1. 如果扫描完成,停止会话
[_captureSession stopRunning];
// 2. 删除预览图层
[self.videoPreviewLayer removeFromSuperlayer];
[self.timer invalidate];
// _captureSession = nil;
// [_scanLayer removeFromSuperlayer];
// [_videoPreviewLayer removeFromSuperlayer];
}
@end