欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-21 13:36:46
前言 首先说明的是:原生的二维码扫描有一个坑,那就是扫描范围的确定。只要记得扫描范围是x与y互换位置,w与h互换位置,就没有什么问题了。 下面进入正题: 1....

前言

首先说明的是:原生的二维码扫描有一个坑,那就是扫描范围的确定。只要记得扫描范围是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;
 }];
}

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

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

总结

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

上一篇:

下一篇: