原生二维码的运用
现在很多项目都需要运用到二维码,大部分人可能用的都是第三方吧,但是经过测试发现苹果原生的扫描效率比他们高,就决定还是用苹果原生的吧,废话不多说,上代码
1 // 1.获取输入设备(摄像头) 2 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 3 // 2.根据输入设备创建输入对象 4 AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:NULL]; 5 6 if (input==nil) { 7 return; 8 } 9 // 3.创建输出对象 10 AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; 11 // 4.设置代理监听输出对象输出的数据 12 [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; 13 14 // 5.创建会话(桥梁) 15 AVCaptureSession *session = [[AVCaptureSession alloc] init]; 16 // 6.添加输入和输出到会话中(判断session是否已满) 17 if ([session canAddInput:input]) { 18 [session addInput:input]; 19 } 20 if ([session canAddOutput:output]) { 21 [session addOutput:output]; 22 } 23 // 7.告诉输出对象, 需要输出什么样的数据 (二维码还是条形码) 24 output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeUPCECode,AVMetadataObjectTypeCode39Code,AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeAztecCode,AVMetadataObjectTypeCode93Code,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeCode39Mod43Code]; 25 26 // 8.创建预览图层 27 AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session]; 28 [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 29 previewLayer.frame = self.view.bounds; 30 [self.view.layer insertSublayer:previewLayer atIndex:0]; 31 32 //设置感应区域 33 // CGRect rect = CGRectMake((WIDTH_FULL_SCREEN - imageSize) / 2, originalTop, imageSize, imageSize); 34 // CGRect intertRect = [previewLayer metadataOutputRectOfInterestForRect:rect]; 35 // CGRect layerRect = [previewLayer rectForMetadataOutputRectOfInterest:intertRect]; 36 // NSLog(@"%@, %@",NSStringFromCGRect(intertRect),NSStringFromCGRect(layerRect)); 37 // output.rectOfInterest = layerRect;//[previewLayer metadataOutputRectOfInterestForRect:rect]; 38 39 // 8.开始扫描数据 40 [session startRunning]; 41 self.session = session; 42 43 //设置中空区域 44 UIView *maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, WIDTH_FULL_SCREEN, HEIGHT_FULL_VIEW)]; 45 maskView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]; 46 [self.view addSubview:maskView]; 47 [self.view bringSubviewToFront:self.flashButton]; 48 UIBezierPath *rectPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, WIDTH_FULL_SCREEN, HEIGHT_FULL_VIEW)]; 49 [rectPath appendPath:[[UIBezierPath bezierPathWithRoundedRect:CGRectMake((WIDTH_FULL_SCREEN - imageSize) / 2, originalTop, imageSize, imageSize) cornerRadius:1] bezierPathByReversingPath]]; 50 CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 51 shapeLayer.path = rectPath.CGPath; 52 maskView.layer.mask = shapeLayer; 53 } 54 55 #pragma mark - AVCaptureMetadataOutputObjectsDelegate 56 // 扫描到数据时会调用 57 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ 58 if (metadataObjects.count > 0) { 59 // 1.停止扫描 60 [self.session stopRunning]; 61 // 2.停止冲击波 62 [self.link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 63 64 // 3.取出扫描到得数据 65 AVMetadataMachineReadableCodeObject *obj = [metadataObjects lastObject]; 66 67 //处理结果 68 UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:@"扫描结果" message:[obj stringValue] preferredStyle:UIAlertControllerStyleAlert]; 69 [alertCtrl addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 70 [self.session startRunning]; 71 [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 72 }]]; 73 [self presentViewController:alertCtrl animated:YES completion:nil]; 74 } 75 }