本次内容的效果图
.h文件
#import "RootViewController.h"
@interface SQCodeViewController : RootViewController//继承根视图,主要继承根视图的导航控制器
@end
.m文件
#import "SQCodeViewController.h"
#import <AVFoundation/AVFoundation.h>//原生二维码扫描必须导入这个框架
#define QRCodeWidth 260.0 //正方形二维码的边长
#define SCREENWidth [UIScreenmainScreen].bounds.size.width //设备屏幕的宽度
#define SCREENHeight [UIScreen mainScreen].bounds.size.height //设备屏幕的高度
@interface SQCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic,strong)AVCaptureSession *session;
@end
@implementation SQCodeViewController
- (void)viewDidLoad {
[superviewDidLoad];
[self onSetTitleView:@"二维码扫描结果"type:TitleLogo];//调用根视图的方法,自定义导航控制器的样式。这个根据读者的实际情况而定。
self.navigationController.toolbarHidden = YES;//如果你的根视图有底部工具栏,这行代码可以隐藏底部的工具栏
[self setupMaskView];//设置扫描区域之外的阴影视图
[self setupScanWindowView];//设置扫描二维码区域的视图
[self beginScanning];//开始扫二维码
}
- (void)setupMaskView
{
//设置统一的视图颜色和视图的透明度
UIColor *color = [UIColor blackColor];
float alpha = 0.7;
//设置扫描区域外部上部的视图
UIView *topView = [[UIView alloc]init];
topView.frame = CGRectMake(0, 64, SCREENWidth, (SCREENHeight-64-QRCodeWidth)/2.0-64);
topView.backgroundColor = color;
topView.alpha = alpha;
//设置扫描区域外部左边的视图
UIView *leftView = [[UIView alloc]init];
leftView.frame = CGRectMake(0, 64+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,64+topView.frame.size.height, (SCREENWidth-QRCodeWidth)/2.0,QRCodeWidth);
rightView.backgroundColor = color;
rightView.alpha = alpha;
//设置扫描区域外部底部的视图
UIView *botView = [[UIViewalloc]init];
botView.frame = CGRectMake(0, 64+QRCodeWidth+topView.frame.size.height,SCREENWidth,SCREENHeight-64-QRCodeWidth-topView.frame.size.height);
botView.backgroundColor = color;
botView.alpha = alpha;
//将设置好的扫描二维码区域之外的视图添加到视图图层上
[self.viewaddSubview:topView];
[self.viewaddSubview:leftView];
[self.viewaddSubview:rightView];
[self.viewaddSubview:botView];
}
- (void)setupScanWindowView
{
//设置扫描区域的位置(考虑导航栏和电池条的高度为64)
UIView *scanWindow = [[UIViewalloc]initWithFrame:CGRectMake((SCREENWidth-QRCodeWidth)/2.0,(SCREENHeight-QRCodeWidth-64)/2.0,QRCodeWidth,QRCodeWidth)];
scanWindow.clipsToBounds = YES;
[self.viewaddSubview:scanWindow];
//设置扫描区域的动画效果
CGFloat scanNetImageViewH = 241;
CGFloat scanNetImageViewW = scanWindow.frame.size.width;
UIImageView *scanNetImageView = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"scan_net"]];
scanNetImageView.frame = CGRectMake(0, -scanNetImageViewH, scanNetImageViewW, scanNetImageViewH);
CABasicAnimation *scanNetAnimation = [CABasicAnimationanimation];
scanNetAnimation.keyPath =@"transform.translation.y";
scanNetAnimation.byValue = @(QRCodeWidth);
scanNetAnimation.duration = 1.0;
scanNetAnimation.repeatCount = MAXFLOAT;
[scanNetImageView.layer addAnimation:scanNetAnimation forKey:nil];
[scanWindow addSubview:scanNetImageView];
//设置扫描区域的四个角的边框
CGFloat buttonWH = 18;
UIButton *topLeft = [[UIButtonalloc]initWithFrame:CGRectMake(0,0, buttonWH, buttonWH)];
[topLeft setImage:[UIImageimageNamed:@"scan_1"]forState:UIControlStateNormal];
[scanWindow addSubview:topLeft];
UIButton *topRight = [[UIButtonalloc]initWithFrame:CGRectMake(QRCodeWidth - buttonWH,0, buttonWH, buttonWH)];
[topRight setImage:[UIImageimageNamed:@"scan_2"]forState:UIControlStateNormal];
[scanWindow addSubview:topRight];
UIButton *bottomLeft = [[UIButtonalloc]initWithFrame:CGRectMake(0,QRCodeWidth - buttonWH, buttonWH, buttonWH)];
[bottomLeft setImage:[UIImageimageNamed:@"scan_3"]forState:UIControlStateNormal];
[scanWindow addSubview:bottomLeft];
UIButton *bottomRight = [[UIButtonalloc]initWithFrame:CGRectMake(QRCodeWidth-buttonWH,QRCodeWidth-buttonWH, buttonWH, buttonWH)];
[bottomRight setImage:[UIImageimageNamed:@"scan_4"]forState:UIControlStateNormal];
[scanWindow addSubview:bottomRight];
}
- (void)beginScanning
{
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInputdeviceInputWithDevice:deviceerror:nil];
if (!input) return;
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutputalloc]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/self.SCREENWidth;
output.rectOfInterest = CGRectMake(x, y, width, height);
//设置代理在主线程里刷新
[output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];
//初始化链接对象
_session = [[AVCaptureSessionalloc]init];
//高质量采集率
[_sessionsetSessionPreset:AVCaptureSessionPresetHigh];
[_session addInput:input];
[_session addOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayerlayerWithSession:_session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.view.layer.bounds;
[self.view.layerinsertSublayer:layeratIndex:0];
//开始捕获
[_sessionstartRunning];
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
[_session stopRunning];
//得到二维码上的所有数据
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjectsobjectAtIndex :0 ];
NSString *str = metadataObject.stringValue;
NSLog(@"%@",str);
}
}