# 掃描二維碼
### 以下是.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. 攝像頭設(shè)備
AVCaptureDevice * captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//2.用captureDeviece創(chuàng)建輸入流
// 因為模擬器是沒有攝像頭的,因此在此做一個判斷
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (error) {
NSLog(@"沒有攝像頭-%@", error.localizedDescription);
//? ? ? ? return;
}
//3.創(chuàng)建媒體數(shù)據(jù)輸出流
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. 拍攝會話(設(shè)置輸出代理)
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
// 4.1 設(shè)置輸出的格式(媒體的數(shù)據(jù)類型)
// 提示:一定要先設(shè)置會話的輸出為output之后,再指定輸出的元數(shù)據(jù)類型!
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
//實例化預(yù)覽圖層(用來讓用戶能夠看到掃描情況)
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
// 5.1 設(shè)置preview圖層的屬性(預(yù)覽圖層的填充模式)
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
// 5.2 設(shè)置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); //設(shè)置陰影的偏移量
_scanLayer.shadowRadius = 10.0;? //設(shè)置陰影的半徑
_scanLayer.shadowColor = [UIColor purpleColor].CGColor; //設(shè)置陰影的顏色為紫色
_scanLayer.shadowOpacity = 0.8; //設(shè)置陰影的不透明度
_scanLayer.backgroundColor = [UIColor colorWithRed:0.737 green:0.341 blue:0.965 alpha:1.000].CGColor;
[self.boxView.layer addSublayer:_scanLayer];
//設(shè)置掃描區(qū)域頂部透明圖層
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];
//設(shè)置掃描區(qū)域底部透明圖層
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];
//設(shè)置掃描區(qū)域左部透明圖層
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];
//設(shè)置掃描區(qū)域右部透明圖層
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,并且完成轉(zhuǎn)換
// 如果QRCode的內(nèi)容越大,轉(zhuǎn)換需要的時間就越長
-(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 里面包含的信息 比如判斷優(yōu)惠券的有效期 需要截取字符串 下面不具有實際意義
*/
if(!metadataObj.stringValue){//實際判斷有效性條件不是這樣寫的
dispatch_sync(dispatch_get_main_queue(), ^{
//添加數(shù)據(jù)成功了
[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:@"設(shè)置密碼"]];
imageView.center=CGPointMake(150, 82.5);
[view addSubview:imageView];
UILabel * label = [[UILabel alloc]init];
label.text = @"現(xiàn)金券已經(jīng)過期";
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(), ^{
//添加數(shù)據(jù)成功了
[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 = @"現(xiàn)金券有效";
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. 刪除預(yù)覽圖層
[self.videoPreviewLayer removeFromSuperlayer];
[self.timer invalidate];
//? ? _captureSession = nil;
//? ? [_scanLayer removeFromSuperlayer];
//? ? [_videoPreviewLayer removeFromSuperlayer];
}
@end