iOS 原生二维码扫描

哎 关于限制扫码范围的控制,弄了老夫好久,还是不尽如意

.h

 1 //
 2 //  LIUScanTwoDimensionalCode.h
 3 //  YouYouShoppingCenter
 4 //
 5 //  Created by liujun on 15/7/28.
 6 //  Copyright (c) 2015年 刘俊. All rights reserved.
 7 //
 8
 9 #import <UIKit/UIKit.h>
10 #import <AVFoundation/AVFoundation.h>
11
12 typedef void (^SuccessBlock) (NSString *str);
13
14 @class LIUScanTwoDimensionalCode;
15
16 @protocol LIUScanTwoDimensionalCodeDelegate <NSObject>
17
18 - (void)scanSuccess:(NSString *)str AndScanObj:(LIUScanTwoDimensionalCode *)obj;
19
20 @end
21
22 @interface LIUScanTwoDimensionalCode : UIView
23
24 - (void)startScanSuccess:(SuccessBlock)successBlock;
25 - (void)start;
26 - (void)dismiss;
27
28 @property (nonatomic,weak)id<LIUScanTwoDimensionalCodeDelegate> delegate;
29
30 @end

.m

  1 //
  2 //  LIUScanTwoDimensionalCode.m
  3 //  YouYouShoppingCenter
  4 //
  5 //  Created by liujun on 15/7/28.
  6 //  Copyright (c) 2015年 刘俊. All rights reserved.
  7 //
  8
  9 #define kScreenBounds           [UIScreen mainScreen].bounds
 10
 11 #define kWidth(W)               W/self.bounds.size.width
 12 #define kHeight(H)              H/self.bounds.size.height
 13
 14 #import "LIUScanTwoDimensionalCode.h"
 15
 16 @interface LIUScanTwoDimensionalCode ()<AVCaptureMetadataOutputObjectsDelegate>
 17
 18 @property(nonatomic,strong)AVCaptureDevice *scanDevice; //扫描设备
 19
 20 @property(nonatomic,strong)AVCaptureInput *input; //输入流
 21
 22 @property(nonatomic,strong)AVCaptureMetadataOutput *output; //输出的数据流
 23
 24 @property(nonatomic,strong)AVCaptureSession *session;   //捕捉会话
 25
 26 @property(nonatomic,strong)AVCaptureVideoPreviewLayer *previewLayer; //展示layour
 27
 28 @property(nonatomic,strong)UIView *boxView;
 29 @property(nonatomic,strong)CALayer *scanLayer;
 30 @property(nonatomic,strong)NSTimer *timer;
 31 @property(nonatomic,strong)SuccessBlock successBlock;
 32
 33 @end
 34
 35 @implementation LIUScanTwoDimensionalCode
 36
 37 - (void)startScanSuccess:(SuccessBlock)successBlock {
 38      self.successBlock = successBlock;
 39     [self start];
 40 }
 41
 42 - (void)start {
 43     //10 开始扫描
 44     [self.session startRunning];
 45 }
 46
 47 - (instancetype)initWithFrame:(CGRect)frame {
 48     if (self = [super initWithFrame:frame]) {
 49         [self creatScanSub];
 50     }
 51     return self;
 52 }
 53
 54 //初始化各种扫描控件
 55 - (void)creatScanSub {
 56
 57     //1.获取设备号
 58     self.scanDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 59
 60     //2.创建输入输出流
 61     NSError *error;
 62     {
 63         self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.scanDevice error:&error];
 64         if (!self.input) {
 65             NSLog(@"%@",error);
 66             return;
 67         }
 68         self.output = [[AVCaptureMetadataOutput alloc]init];
 69     }
 70
 71     //3.实例化捕捉会话
 72     {
 73         self.session = [[AVCaptureSession alloc]init];
 74         //3.1
 75         [self.session addInput:self.input];
 76         //3.2
 77         [self.session addOutput:self.output];
 78     }
 79
 80     //4.创建串行队列并添加到会话中
 81     {
 82         dispatch_queue_t dispatchQueue;
 83         dispatchQueue = dispatch_queue_create("myqueue", NULL);
 84         //4.1将媒体输出流添加到会话中
 85         [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
 86         //4.2设置输出媒体数据类型为QRCode
 87         [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
 88     }
 89
 90     //5.实例化预览图层
 91     self.previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
 92     //6.设置预览图层的填充方式
 93     [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
 94     //7.设置图层的frame
 95     [self.previewLayer setFrame:self.layer.bounds];
 96     //8.讲图层添加到预览view的图层上
 97     [self.layer addSublayer:self.previewLayer];
 98
 99     //9.设置扫描范围//kHeight((self.bounds.size.height-200)*0.5)  kWidth(self.bounds.size.width-((self.bounds.size.width-200)*0.5))
100     //这里扫描范围的控制是以又顶点为原点(0,0,1,1),然后interest的x,y,width,height都相互交换了,注意这点
101     self.output.rectOfInterest = CGRectMake(kHeight((self.bounds.size.height-200)*0.5),kWidth((self.bounds.size.width-200)*0.5),kHeight(200),kWidth(200));
102     //9.1扫描框
103     //self.boxView = [[UIView alloc]initWithFrame:CGRectMake((self.bounds.size.width-200)*0.5,(self.bounds.size.height-200)*0.5,200, 200)];
104     //self.boxView = [[UIView alloc]initWithFrame:CGRectMake((kWidth(self.bounds.size.width-((self.bounds.size.width-200)*0.5))-kWidth(200))*self.bounds.size.width, kHeight((self.bounds.size.height-200)*0.5)*self.bounds.size.height, kWidth(200)*self.bounds.size.height, kHeight(200)*self.bounds.size.height)];
105     self.boxView = [[UIView alloc]initWithFrame:CGRectMake((self.bounds.size.width - (self.bounds.size.width-200)*0.5)-200,kHeight((self.bounds.size.height-200)*0.5)*self.bounds.size.height, kWidth(200)*self.bounds.size.width, kHeight(200)*self.bounds.size.height)];
106     self.boxView.layer.borderColor = [UIColor greenColor].CGColor;
107     self.boxView.layer.borderWidth = 1.f;
108     [self addSubview:self.boxView];
109     //9.2扫描线
110     self.scanLayer = [[CALayer alloc]init];
111     self.scanLayer.frame = CGRectMake(0, 0, self.boxView.bounds.size.width, 1);
112     self.scanLayer.backgroundColor = [UIColor brownColor].CGColor;
113     [self.boxView.layer addSublayer:self.scanLayer];
114
115     self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(moveScanLayer:) userInfo:nil repeats:YES];
116
117
118 }
119
120 //移动扫描线
121 - (void)moveScanLayer:(NSTimer *)timer {
122
123     CGRect frame = self.scanLayer.frame;
124     if (_boxView.frame.size.height < self.scanLayer.frame.origin.y) {
125         frame.origin.y = 0;
126         self.scanLayer.frame = frame;
127     }else{
128         frame.origin.y += 5;
129         [UIView animateWithDuration:0.1f animations:^{
130             self.scanLayer.frame = frame;
131         }];
132     }
133 }
134
135 //代理
136 #pragma --mark AVCaptureMetadaOutputdelegate
137 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
138
139     //判断是否有数据
140     if (metadataObjects != nil && metadataObjects.count > 0) {
141         AVMetadataMachineReadableCodeObject *metaDataObj = [metadataObjects firstObject];
142         //判断回传的数据类型
143         if ([[metaDataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
144             [self stopReading];
145             [self.delegate scanSuccess:[metaDataObj stringValue] AndScanObj:self];
146             if (self.successBlock) {
147                 self.successBlock([metaDataObj stringValue]);
148             }
149
150             //[self stopReading];
151         }
152     }
153
154 }
155
156 - (void)stopReading {
157     [self.session stopRunning];
158     self.session = nil;
159     [self.timer invalidate];
160 //    [self.scanLayer removeFromSuperlayer];
161 //    [self.previewLayer removeFromSuperlayer];
162 }
163
164
165 - (void)dismiss {
166     [self removeFromSuperview];
167 }
168
169 - (void)cancle:(UIButton *)sender {
170     [self dismiss];
171 }
172
173
174
175 @end
时间: 2024-12-16 10:56:56

iOS 原生二维码扫描的相关文章

二维码扫描(iOS原生二维码扫描)

一.关于二维码扫描的第三方库有很多:例如比较常用的两个 1.ZBar SDK ZBar为我们提供了两种使用方式,一种是直接调用ZBar提供的ZBarReaderViewController打开一个扫描界面,另一种方式是使用ZBar提供的可以嵌在其他视图中的ZBarReaderView,实际项目中我们更可能会使用第二种方式,这可以让我们对界面做更多的定制,详细的百度查找相关文档来看. 2.ZXing(Github镜像地址)是一个开源的条码生成和扫描库(开源协议为Apache2.0).它不但支持众多

iOS 原生二维码扫描(可限制扫描区域)

写这篇文章的主要原因不是展示如何使用 AVFoundation   来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了苹果原生的扫描. 原生的好处就是扫描特别快效率特别高,但是遇到一个问题就是不知道怎么去限制扫描范围. 还是先简单说一下怎么使用来进行二维码扫描吧. 首先是要用到的几个类 @property (strong,nonatomic)AVCaptureDevice * device; @propert

【转】 iOS 原生二维码扫描(可限制扫描区域)

在用 AVFoundation 完成扫码后,遇到2个问题: 1,如何限制扫描范围? 2.条形码如何扫描? 一位朋友的文章帮助了我,特地转来,可以帮到有需要的朋友. 原文:http://www.2cto.com/kf/201411/356046.html 写这篇文章的主要原因不是展示如何使用 AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了苹果原生的扫描. 原生的好处就是扫描特别快效

iOS 原生二维码扫描,带扫描框和扫描过程动画

在代码中使用了相对布局框架Masonry 准备两张图片,一张是扫描边框,一张是扫描时的细线分别命名 scanFrame.png和scanLine.png并提前放入工程 导入相对布局头文件 #define MAS_SHORTHAND #define MAS_SHORTHAND_GLOBALS #import "Masonry.h" 导入依赖头文件 #import <AVFoundation/AVFoundation.h> 具体代码如下: static const char *

iOS之原生二维码扫描

做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framework框架到你工程中build phase的"Link Binary With Libraries"之下,然后就可以开始了. 一.做好准备工作,搭建UI IBOutlet.IBAction如下: @property (weak, nonatomic) IBOutlet UIView *vie

iOS:原生二维码扫描

做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framework框架到你工程中build phase的"Link Binary With Libraries"之下,然后就可以开始了. 一.做好准备工作,搭建UI UI效果如图 IBOutlet.IBAction如下: @property (weak, nonatomic) IBOutlet UIVi

iOS开发-二维码扫描和应用跳转

iOS开发-二维码扫描和应用跳转 序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar.使用时集成麻烦,出错也不方便调试.在iOS7之后,苹果自身提供了二维码的扫描功能,从效率上来说,原生的二维码远高于这些第三方框架.本文讲解如何使用原生框架实现二维码扫描功能,并且进行扫描后的项目跳转.ps:本期的源代码会在文章结尾给出链接 扫描相关类 二维码扫描需要获取摄像头并读取

苹果原生二维码扫描功能——可限制扫描区域

使用原生的好处就是扫描特别快效率特别高,使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(默认的是全屏扫描) 首先是要用到的几个类 @property ( strong , nonatomic ) AVCaptureDevice * device; @property ( strong , nonatomic ) AVCaptureDeviceInput * input; @property ( strong , nonatomic ) AVCaptureMe

iOS 系统二维码扫描(可限制扫描区域)

使用 AVFoundation系统库来进行二维码扫描并且限制扫描二维码的范围.(因为默认的是全屏扫描) -(void)beginCode { //1.摄像头设备 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; /* // Media types AVMediaTypeVideo AVMediaTypeAudio AVMediaTypeText AVMediaTypeC