#import <AVFoundation/AVFoundation.h>
#define QRCodeWidth 260.0 //正方形二维码的边长
@interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic,strong)AVCaptureSession * session;
@property (nonatomic,strong)AVCaptureVideoPreviewLayer * preview;
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title = @"扫一扫";
self.navigationController.toolbarHidden = YES;//如果你的根视图有底部工具栏,这行代码可以隐藏底部的工具栏
[self setupMaskView];//设置扫描区域之外的阴影视图
[self setupScanWindowView];//设置扫描二维码区域的视图
[self beginScanning];//开始扫二维码
}
- (void)setupMaskView{
//设置统一的视图颜色和视图的透明度
UIColor*color = [UIColorblackColor];
floatalpha =0.7;
//设置扫描区域外部上部的视图
UIView*topView = [[UIViewalloc]init];
topView.frame = CGRectMake(0, 0, ScreenWidth, (ScreenHeight-64-QRCodeWidth)/2.0-64);
topView.backgroundColor= color;
topView.alpha= alpha;
//设置扫描区域外部左边的视图
UIView*leftView = [[UIViewalloc]init];
leftView.frame=CGRectMake(0, topView.frame.size.height, (ScreenWidth-QRCodeWidth)/2.0,QRCodeWidth);
leftView.backgroundColor= color;
leftView.alpha= alpha;
//设置扫描区域外部右边的视图
UIView*rightView = [[UIViewalloc]init];
rightView.frame = CGRectMake((ScreenWidth-QRCodeWidth)/2.0+QRCodeWidth,topView.frame.size.height, (ScreenWidth-QRCodeWidth)/2.0,QRCodeWidth);
rightView.backgroundColor= color;
rightView.alpha= alpha;
//设置扫描区域外部底部的视图
UIView*botView = [[UIViewalloc]init];
botView.frame=CGRectMake(0,QRCodeWidth+topView.frame.size.height,ScreenWidth,ScreenHeight-64-QRCodeWidth-topView.frame.size.height);
botView.backgroundColor= color;
botView.alpha= alpha;
UILabel*signL = [[UILabelalloc]init];
[botViewaddSubview:signL];
[signLmas_makeConstraints:^(MASConstraintMaker*make) {
make.top.equalTo(botView.mas_top).offset(10);
make.centerX.equalTo(botView.mas_centerX);
}];
signL.text = @"将二维码放入框内即可自动扫描";
signL.textColor = [UIColor whiteColor];
signL.font = [UIFont systemFontOfSize:13];
//将设置好的扫描二维码区域之外的视图添加到视图图层上
[self.viewaddSubview:topView];
[self.viewaddSubview:leftView];
[self.viewaddSubview:rightView];
[self.viewaddSubview:botView];
}
- (void)setupScanWindowView{
//设置扫描区域的位置(考虑导航栏和电池条的高度为64)
UIView *scanWindow = [[UIView alloc]initWithFrame:CGRectMake((ScreenWidth-QRCodeWidth)/2.0,(ScreenHeight-QRCodeWidth-64)/2.0-64,QRCodeWidth,QRCodeWidth)];
scanWindow.clipsToBounds=YES;
[self.viewaddSubview:scanWindow];
//设置扫描区域的动画效果
CGFloatscanNetImageViewH =241;
CGFloatscanNetImageViewW = scanWindow.frame.size.width;
UIImageView*scanNetImageView = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"scan_net"]];
scanNetImageView.frame=CGRectMake(0, -scanNetImageViewH, scanNetImageViewW, scanNetImageViewH);
CABasicAnimation *scanNetAnimation = [CABasicAnimation animation];
scanNetAnimation.keyPath =@"transform.translation.y";
scanNetAnimation.byValue=@(QRCodeWidth);
scanNetAnimation.duration=1.0;
scanNetAnimation.repeatCount=MAXFLOAT;
[scanNetImageView.layeraddAnimation:scanNetAnimationforKey:nil];
[scanWindowaddSubview:scanNetImageView];
//设置扫描区域的四个角的边框
CGFloatbuttonWH =18;
UIButton*topLeft = [[UIButtonalloc]initWithFrame:CGRectMake(0,0, buttonWH, buttonWH)];
[topLeftsetImage:[UIImage imageNamed:@"scan_1"]forState:UIControlStateNormal];
[scanWindowaddSubview:topLeft];
UIButton*topRight = [[UIButtonalloc]initWithFrame:CGRectMake(QRCodeWidth- buttonWH,0, buttonWH, buttonWH)];
[topRightsetImage:[UIImage imageNamed:@"scan_2"]forState:UIControlStateNormal];
[scanWindowaddSubview:topRight];
UIButton*bottomLeft = [[UIButtonalloc]initWithFrame:CGRectMake(0,QRCodeWidth- buttonWH, buttonWH, buttonWH)];
[bottomLeftsetImage:[UIImage imageNamed:@"scan_3"]forState:UIControlStateNormal];
[scanWindowaddSubview:bottomLeft];
UIButton*bottomRight = [[UIButtonalloc]initWithFrame:CGRectMake(QRCodeWidth-buttonWH,QRCodeWidth-buttonWH, buttonWH, buttonWH)];
[bottomRightsetImage:[UIImage imageNamed:@"scan_4"]forState:UIControlStateNormal];
[scanWindowaddSubview:bottomRight];
}
- (void)beginScanning{
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if(!input)return;
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//特别注意的地方:有效的扫描区域,定位是以设置的右顶点为原点。屏幕宽所在的那条线为y轴,屏幕高所在的线为x轴
CGFloat x = ((ScreenHeight-QRCodeWidth-64)/2.0)/ScreenHeight;
CGFloat y = ((ScreenWidth-QRCodeWidth)/2.0)/ScreenWidth;
CGFloat width = QRCodeWidth/ScreenHeight;
CGFloat height = QRCodeWidth/ScreenWidth;
output.rectOfInterest=CGRectMake(x, y, width, height);
//设置代理在主线程里刷新
[outputsetMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//初始化链接对象
_session = [[AVCaptureSession alloc]init];
//高质量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
[_sessionaddInput:input];
[_sessionaddOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:0];
//开始捕获
[_session startRunning];
}
-(void)captureOutput:(AVCaptureOutput*)captureOutputdidOutputMetadataObjects:(NSArray*)metadataObjectsfromConnection:(AVCaptureConnection*)connection{
if(metadataObjects.count>0) {
[_sessionstopRunning];
//得到二维码上的所有数据
AVMetadataMachineReadableCodeObject* metadataObject = [metadataObjectsobjectAtIndex:0];
//获取到扫描结果
NSString*str = metadataObject.stringValue;
NSLog(@"字符串:%@",str);
}
}
网友评论