iOS 原生二维码扫描

来源:互联网 发布:欧缇丽淘宝官网是真假 编辑:程序博客网 时间:2024/05/21 11:57
哎 关于限制扫码范围的控制,弄了老夫好久,还是不尽如意

.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 @end21 22 @interface LIUScanTwoDimensionalCode : UIView23 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 AVCaptureMetadaOutputdelegate137 - (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

 

0 0