哎 关于限制扫码范围的控制,弄了老夫好久,还是不尽如意
.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