// // YHScanQRCodeVC.m // YHScrollView_Test // // Created by Jim on 2021/9/3. // #import "YHScanQRCodeVC.h" #import <AVFoundation/AVFoundation.h> #define TOP (KScreenHeight-220)/2 #define LEFT (KScreenWidth-220)/2 #define kScanRect CGRectMake(LEFT, TOP, 220, 220) @interface YHScanQRCodeVC ()<AVCaptureMetadataOutputObjectsDelegate>{ int num; BOOL upOrdown; CAShapeLayer *cropLayer; } @property (strong,nonatomic)AVCaptureDevice * device; @property (strong,nonatomic)AVCaptureDeviceInput * input; @property (strong,nonatomic)AVCaptureMetadataOutput * output; @property (strong,nonatomic)AVCaptureSession * session; @property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview; @property (nonatomic, strong) UIImageView * line; @property (nonatomic, strong) NSTimer * timer; @end @implementation YHScanQRCodeVC - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.navigationItem.title = @"扫一扫"; [self configView]; } -(void)configView{ UIImageView * imageView = [[UIImageView alloc]initWithFrame:kScanRect]; imageView.image = [UIImage imageNamed:@"pick_bg"]; [self.view addSubview:imageView]; upOrdown = NO; num =0; _line = [[UIImageView alloc] initWithFrame:CGRectMake(LEFT, TOP+10, 220, 2)]; _line.image = [UIImage imageNamed:@"line.png"]; [self.view addSubview:_line]; self.timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES]; } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.navigationController setNavigationBarHidden:NO]; [self setCropRect:kScanRect]; [self performSelector:@selector(setupCamera) withObject:nil afterDelay:0.1]; } -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self.navigationController setNavigationBarHidden:YES]; } -(void)animation1 { if (upOrdown == NO) { num ++; _line.frame = CGRectMake(LEFT, TOP+10+2*num, 220, 2); if (2*num == 200) { upOrdown = YES; } } else { num --; _line.frame = CGRectMake(LEFT, TOP+10+2*num, 220, 2); if (num == 0) { upOrdown = NO; } } } - (void)setCropRect:(CGRect)cropRect{ cropLayer = [[CAShapeLayer alloc] init]; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, nil, cropRect); CGPathAddRect(path, nil, self.view.bounds); [cropLayer setFillRule:kCAFillRuleEvenOdd]; [cropLayer setPath:path]; [cropLayer setFillColor:[UIColor blackColor].CGColor]; [cropLayer setOpacity:0.6]; [cropLayer setNeedsDisplay]; [self.view.layer addSublayer:cropLayer]; } - (void)setupCamera { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if (device==nil) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"设备没有摄像头" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { }]]; [self presentViewController:alert animated:YES completion:nil]; return; } // Device self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; // Input self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil]; // Output self.output = [[AVCaptureMetadataOutput alloc]init]; [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //设置扫描区域 CGFloat top = TOP/KScreenHeight; CGFloat left = LEFT/KScreenWidth; CGFloat width = 220/KScreenWidth; CGFloat height = 220/KScreenHeight; ///top 与 left 互换 width 与 height 互换 [self.output setRectOfInterest:CGRectMake(top,left, height, width)]; // Session self.session = [[AVCaptureSession alloc]init]; [self.session setSessionPreset:AVCaptureSessionPresetHigh]; if ([self.session canAddInput:self.input]) { [self.session addInput:self.input]; } if ([self.session canAddOutput:self.output]) { [self.session addOutput:self.output]; } // 条码类型 AVMetadataObjectTypeQRCode self.output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]; // Preview self.preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session]; self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill; self.preview.frame =self.view.layer.bounds; [self.view.layer insertSublayer:self.preview atIndex:0]; // Start [self.session startRunning]; } #pragma mark AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { NSString *stringValue; if ([metadataObjects count] >0) { //停止扫描 [self.session stopRunning]; [self.timer setFireDate:[NSDate distantFuture]]; AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0]; stringValue = metadataObject.stringValue; NSLog(@"扫描结果:%@",stringValue); if (_delegate && [_delegate respondsToSelector:@selector(YHScanQRCodeVC:didFinishScingMediaWithResult:)]) { [_delegate YHScanQRCodeVC:self didFinishScingMediaWithResult:stringValue]; } // UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"扫描结果" message:stringValue preferredStyle:UIAlertControllerStyleAlert]; // [alert addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // if (self.session != nil && self.timer != nil) { // [self.session startRunning]; // [self.timer setFireDate:[NSDate date]]; // } // // }]]; // [self presentViewController:alert animated:YES completion:nil]; } else { NSLog(@"无扫描信息"); return; } } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end