当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS自带原生二维码扫描的实现

iOS自带原生二维码扫描的实现

2019年07月24日  | 移动技术网移动技术  | 我要评论

前言

首先说明的是:原生的二维码扫描有一个坑,那就是扫描范围的确定。只要记得扫描范围是x与y互换位置,w与h互换位置,就没有什么问题了。

下面进入正题:

1.因为使用原生二维码扫描,所以需要加入头文件添加delegate

#import <avfoundation/avfoundation.h>
<avcapturemetadataoutputobjectsdelegate>

2.接着是使用到的类

@property (strong,nonatomic)avcapturedevice * device;
@property (strong,nonatomic)avcapturedeviceinput * input;
@property (strong,nonatomic)avcapturemetadataoutput * output;
@property (strong,nonatomic)avcapturesession * session;
@property (weak, nonatomic) iboutlet uiview *outputview;//xib中扫描的view
@property (strong,nonatomic)avcapturevideopreviewlayer * preview;
@property (strong, nonatomic) nstimer * timer;//为了做扫描动画的定时器
@property (strong, nonatomic) uiimageview * lineimage;//扫描动画的横线

3.懒加载一个扫描动画的图片

-(uiimageview *)lineimage{
 if (!_lineimage) {
  cgfloat outputw = self.outputview.frame.size.width;
  _lineimage = [[uiimageview alloc]initwithframe:cgrectmake(0, 0,outputw, 2)];
  _lineimage.image = [uiimage imagenamed:@"ray"];
 }
 return _lineimage;
}

4.使用前的设置,我将它设置在了viewdidload当中

-viewdidload{
[super viewdidload];
 // device
 _device = [avcapturedevice defaultdevicewithmediatype:avmediatypevideo];

 // input
 _input = [avcapturedeviceinput deviceinputwithdevice:self.device error:nil];

 // output
 _output = [[avcapturemetadataoutput alloc]init];
 [_output setmetadataobjectsdelegate:self queue:dispatch_get_main_queue()];

 // session
 _session = [[avcapturesession alloc]init];
 [_session setsessionpreset:avcapturesessionpresethigh];
 //连接输入和输出
 if ([_session canaddinput:self.input])
 {
  [_session addinput:self.input];
 }

 if ([_session canaddoutput:self.output])
 {
  [_session addoutput:self.output];
 }
//设置条码类型
 _output.metadataobjecttypes =@[avmetadataobjecttypeqrcode];

 //设置条码位置
 cgfloat x = (screenw/2-100)/screenw;
 cgfloat y = (screenh/2-100)/screenh;
 cgfloat w = 200/screenw;
 cgfloat h = 200/screenh;
 //设置扫描范围(注意,x与y交互,w与h交换)
 [_output setrectofinterest:cgrectmake(y, x, h, w)];
//添加扫描画面
 _preview =[avcapturevideopreviewlayer layerwithsession:_session];
 _preview.videogravity =avlayervideogravityresizeaspectfill;
 _preview.frame = cgrectmake(0, 0, screenw, screenh);//self.view.layer.bounds;
 [self.view.layer insertsublayer:_preview atindex:0];
 //开始扫描
 [_session startrunning];

//添加扫描动画定时器
[self.outputview addsubview:self.lineimage];
 // do any additional setup after loading the view from its nib.
 _timer = [nstimer scheduledtimerwithtimeinterval:2.5f
           target:self
           selector:@selector(lineaction)
           userinfo:nil
           repeats:yes];
}

5.二维码扫描的代理事件

-(void)captureoutput:(avcaptureoutput *)captureoutput didoutputmetadataobjects:(nsarray *)metadataobjects fromconnection:(avcaptureconnection *)connection
{
 nsstring *stringvalue;
 if ([metadataobjects count] >0){
  //停止扫描
  [_session stoprunning];
  avmetadatamachinereadablecodeobject * metadataobject = [metadataobjects objectatindex:0];
  stringvalue = metadataobject.stringvalue;//stringvalue是扫描拿到的内容,更具内容进行后续工作。
 }
}

6.添加扫描动画的事件

- (void)lineaction{
 cgfloat outputw = self.outputview.frame.size.width;
 cgfloat outputh = self.outputview.frame.size.height;
 [uiview animatewithduration:2.4f animations:^{
  cgrect frame = cgrectmake(0, outputh, outputw, 2);
  self.lineimage.frame = frame;
 } completion:^(bool finished) {
  cgrect frame = cgrectmake(0, 0, outputw, 2);
  self.lineimage.frame = frame;
 }];
}

搞定......最后放上一张效果图

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网