博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS系统原生二维码条形码扫描
阅读量:6072 次
发布时间:2019-06-20

本文共 6059 字,大约阅读时间需要 20 分钟。

 本文讲述如何用系统自带的东东实现二维码扫描的功能:点击当前页面的某个按钮,创建扫描VIEW。细心的小伙伴可以发现 title被改变了,返回按钮被隐藏了。这个代码自己写就行了,与本文关系不大。。。绿色的线会上下跑,不要担心:D

实现效果如下:

  1.在工程中添加框架AVFoundation.framework

  2.声明代理:AVCaptureMetadataOutputObjectsDelegate 。 define 几个东东用来画框、画线:

#define SCANVIEW_EdgeTop 40.0#define SCANVIEW_EdgeLeft 50.0#define TINTCOLOR_ALPHA 0.2 //浅色透明度#define DARKCOLOR_ALPHA 0.5 //深色透明度#define VIEW_WIDTH [UIScreen mainScreen].bounds.size.width#define VIEW_HEIGHT [UIScreen mainScreen].bounds.size.height

 

  3.声明以下属性:

AVCaptureSession * session;//输入输出的中间桥梁    UIView *AVCapView;//此 view 用来放置扫描框、取消按钮、说明 label    UIView *_QrCodeline;//上下移动绿色的线条    NSTimer *_timer;

  4.在某个方法中(我是点击扫描按钮)创建扫描界面,开始扫描:

//创建一个 view 来放置扫描区域、说明 label、取消按钮    UIView *tempView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, [UIScreen mainScreen].bounds.size.height )];    AVCapView = tempView;    AVCapView.backgroundColor = [UIColor colorWithRed:54.f/255 green:53.f/255 blue:58.f/255 alpha:1];        UIButton *cancelBtn = [[UIButton alloc]initWithFrame:CGRectMake(15, [UIScreen mainScreen].bounds.size.height - 100, 50, 25)];    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(15, 268, 290, 60)];    label.numberOfLines = 0;    label.text = @"小提示:将条形码或二维码对准上方区域中心即可";    label.textColor = [UIColor grayColor];    [cancelBtn setTitle:@"取消" forState: UIControlStateNormal];    [cancelBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];    [cancelBtn addTarget:self action:@selector(touchAVCancelBtn) forControlEvents:UIControlEventTouchUpInside];    [AVCapView addSubview:label];    [AVCapView addSubview:cancelBtn];    [self.view addSubview:AVCapView];            //画上边框    UIView *topView = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop, VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft, 1)];    topView.backgroundColor = [UIColor whiteColor];    [AVCapView addSubview:topView];        //画左边框    UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop , 1,VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft )];    leftView.backgroundColor = [UIColor whiteColor];    [AVCapView addSubview:leftView];        //画右边框    UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft + VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop , 1,VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + 1)];    rightView.backgroundColor = [UIColor whiteColor];    [AVCapView addSubview:rightView];        //画下边框    UIView *downView = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop + VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft,VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft ,1 )];    downView.backgroundColor = [UIColor whiteColor];    [AVCapView addSubview:downView];        //画中间的基准线    _QrCodeline = [[UIView alloc] initWithFrame:CGRectMake(SCANVIEW_EdgeLeft + 1, SCANVIEW_EdgeTop, VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft - 1, 2)];    _QrCodeline.backgroundColor = [UIColor greenColor];    [AVCapView addSubview:_QrCodeline];            // 先让基准线运动一次,避免定时器的时差    [UIView animateWithDuration:1.2 animations:^{                _QrCodeline.frame = CGRectMake(SCANVIEW_EdgeLeft + 1, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop , VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft - 1, 2);            }];    [self performSelector:@selector(createTimer) withObject:nil afterDelay:0.4];        AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];    //创建输入流    AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];    //创建输出流    AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];    //设置代理 在主线程里刷新    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];        //初始化链接对象    session = [[AVCaptureSession alloc]init];    //高质量采集率    [session setSessionPreset:AVCaptureSessionPresetHigh];        [session addInput:input];    [session addOutput:output];    //设置扫码支持的编码格式(如下设置条形码和二维码兼容)    output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];        AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];    layer.videoGravity=AVLayerVideoGravityResizeAspectFill;    layer.frame = CGRectMake(SCANVIEW_EdgeLeft, SCANVIEW_EdgeTop, VIEW_WIDTH- 2 * SCANVIEW_EdgeLeft, 220);    [AVCapView.layer insertSublayer:layer atIndex:0];    //开始捕获    [session startRunning];

  5.实现定时器、还有基准线的滚动方法

- (void)createTimer{    _timer=[NSTimer scheduledTimerWithTimeInterval:1.1 target:self selector:@selector(moveUpAndDownLine) userInfo:nil repeats:YES];}- (void)stopTimer{    if ([_timer isValid] == YES) {        [_timer invalidate];        _timer = nil;    }    }// 滚来滚去 :D :D :D- (void)moveUpAndDownLine{    CGFloat YY = _QrCodeline.frame.origin.y;        if (YY != VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop ) {        [UIView animateWithDuration:1.2 animations:^{            _QrCodeline.frame = CGRectMake(SCANVIEW_EdgeLeft + 1, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft + SCANVIEW_EdgeTop , VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft - 1,2);        }];    }else {        [UIView animateWithDuration:1.2 animations:^{            _QrCodeline.frame = CGRectMake(SCANVIEW_EdgeLeft + 1, SCANVIEW_EdgeTop, VIEW_WIDTH - 2 * SCANVIEW_EdgeLeft - 1,2);        }];    }}

6.扫描成功后,想干嘛干嘛,就在这个代理方法里面实现就行了

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{    if (metadataObjects.count>0) {        //[session stopRunning];        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];        //输出扫描字符串        NSLog(@"%@",metadataObject.stringValue);        [session stopRunning];        [self stopTimer];        [AVCapView removeFromSuperview];        .....        }}

 

7.如果用户不想扫描了,点击取消按钮:

- (void)touchAVCancelBtn{    [session stopRunning];//摄像也要停止    [self stopTimer];//定时器要停止    [AVCapView removeFromSuperview];//刚刚创建的 view 要移除       ...        }

 

转载于:https://www.cnblogs.com/onlyMyRailGun/p/5320041.html

你可能感兴趣的文章
KVM网络桥接设置方法
查看>>
Puppet学习手册:Puppet Yum安装
查看>>
我的友情链接
查看>>
ansible学习记录
查看>>
网思科技校园网计费解决方案
查看>>
我的友情链接
查看>>
携程 Apollo分布式部署
查看>>
2017 Hackatari Codeathon B. 2Trees(深搜)(想法)
查看>>
单词统计
查看>>
输入一个数字计算圆的面积
查看>>
在Delphi中隐藏程序进程
查看>>
AngularJS PhoneCat代码分析
查看>>
MEF元数据应用说明
查看>>
maven错误解决:编码GBK的不可映射字符
查看>>
2016/4/19 反射
查看>>
SharePoint Wiki发布页面的“保存冲突”
查看>>
oracle 10g 数据库与客户端冲突导致实例创建无监听问题
查看>>
Delphi中读取文本文件的方法(实例一)
查看>>
Linux常用命令
查看>>
Android开源代码解读の使用TelephonyManager获取移动网络信息
查看>>