// // YHScanQRController.m // YHScanQRTool // // Created by Foxconn on 2018/1/29. // Copyright © 2018年 Foxconn. All rights reserved. // #define scanBorderW 0.7 * self.view.bounds.size.width // 扫描内容的 x 值 #define scanBorderX 0.5 * (1 - 0.7) * self.view.bounds.size.width // 扫描内容的 Y 值 #define scanBorderY 0.5 * ((self.view.bounds.size.height ) - scanBorderW) #import "YHScanQRController.h" #import "YHScanQREngineManager.h" #import "YHScanQRView.h" #import "YHAlbumScanQRManager.h" //#import "ZZWHudHelper.h" //#import "PayMoneyController.h" @interface YHScanQRController ()<YHScanQREngineManagerDelegate,YHAlbumScanQRManagerDelegate>{ float _scaleViewMuilte; } @property (nonatomic,strong) YHScanQRView *scanningView; @property (nonatomic,strong) YHScanQREngineManager *manager; @property (nonatomic,strong) UILabel *promptLabel; // 扫描框的X值 @property (nonatomic, assign) float scanViewX; // 扫描框的Y值 @property (nonatomic, assign) float scanViewY; @end @implementation YHScanQRController - (void)viewDidLoad { [super viewDidLoad]; _scaleViewMuilte = 1.0; self.view.backgroundColor = [UIColor whiteColor]; [self createNavigationBtn]; [self judgmentCameraWhetherAuthorized]; [self createFlashLightSender]; [self createDoubleWithPichGesture]; [self.view addSubview:self.promptLabel]; self.navigationItem.title = @"扫码"; UIButton *settingBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [settingBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; [settingBtn setImage:[UIImage imageNamed:@"icon_fanhui"] forState:UIControlStateNormal]; [settingBtn setFrame:CGRectMake(-20, 0, 40, 40)]; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:settingBtn]; } - (void)back{ [self.navigationController popViewControllerAnimated:YES]; } //判断相机是否授权 -(void) judgmentCameraWhetherAuthorized{ AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if (device) { AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if (status == AVAuthorizationStatusNotDetermined) { [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if (granted) { dispatch_sync(dispatch_get_main_queue(), ^{ // 第一次同意访问相机权限 //创建二维码扫描的功能 ios原生 [self createARScan]; //添加扫描框 [self.view addSubview:self.scanningView]; }); } else { // 第一次拒绝了访问相机权限 NSString *message = @"您已经拒绝了访问相机权限"; UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:(UIAlertControllerStyleAlert)]; UIAlertAction *alertsure = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) { //返回 [self.navigationController popViewControllerAnimated:YES]; }]; [alertVC addAction:alertsure]; [self presentViewController:alertVC animated:YES completion:nil]; } }]; } else if (status == AVAuthorizationStatusAuthorized) { //创建二维码扫描的功能 ios原生 [self createARScan]; //添加扫描框 [self.view addSubview:self.scanningView]; } else if (status == AVAuthorizationStatusDenied) { // 用户拒绝当前应用访问相机 NSString *message = @"请去-> [设置 - 隐私 - 相机 ] 打开访问开关"; UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:(UIAlertControllerStyleAlert)]; UIAlertAction *alertsure = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) { //跳转到系统类 NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if([[UIApplication sharedApplication] canOpenURL:url]) { NSURL*url =[NSURL URLWithString:UIApplicationOpenSettingsURLString]; [[UIApplication sharedApplication] openURL:url]; } }]; [alertVC addAction:alertsure]; [self presentViewController:alertVC animated:YES completion:nil]; } else if (status == AVAuthorizationStatusRestricted) { NSString *message = @"因为系统原因, 无法访问相机"; [self createAlertViewWithMessage:message]; } } else { NSString *message = @"未检测到您的摄像头"; [self createAlertViewWithMessage:message]; } } #pragma mark - 相机按钮 -(void) createNavigationBtn{ if (_albumTextColor == nil) { _albumTextColor = [UIColor colorWithRed: 21/ 255.0f green: 126/ 255.0f blue: 251/ 255.0f alpha:1.0]; } UIButton *rightButton = [[UIButton alloc] init]; [rightButton setTitle:@"相册" forState:UIControlStateNormal]; [rightButton setTitleColor:[UIColor blackColor] forState:(UIControlStateNormal)]; [rightButton sizeToFit]; [rightButton addTarget:self action:@selector(rightButtonAction) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton]; self.navigationItem.rightBarButtonItem = rightBarButtonItem; } #pragma mark - 相册扫描 -(void)rightButtonAction{ YHAlbumScanQRManager *albumManager = [YHAlbumScanQRManager sharedManager]; [albumManager readQRCodeFromAlbumWithCurrentController:self]; albumManager.delegate = self; if (albumManager.isAlbumAccessAuthorization == YES) { [self.scanningView removeTimer]; } } #pragma mark - 摄像机扫描 -(void)createARScan{ if (_scanViewWidth == 0) { _scanViewWidth = scanBorderW; } if (_scanViewHeight == 0) { _scanViewHeight = scanBorderW; } if (_scanViewX == 0) { _scanViewX = (self.view.bounds.size.width - _scanViewWidth)/2; } if (_scanViewY == 0) { _scanViewY = (self.view.bounds.size.height - _scanViewHeight)/2; } self.manager = [YHScanQREngineManager sharedEngineManager]; NSArray *metadatas = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]; [self.manager setupSessionPreset:AVCaptureSessionPreset1920x1080 metadataObjectTypes:metadatas currentController:self scanViewX:_scanViewX scanViewY:_scanViewY scanViewWidth:_scanViewWidth scanViewHeight:_scanViewHeight]; self.manager.delegate = self; } #pragma mark - YH_AlbumScanQRManagerDelegate -(void)YHAlbumScanQRManagerDidCancelWithImagePickerController:(YHAlbumScanQRManager *)albumManager{ [self.view addSubview:self.scanningView]; } -(void)YHAlbumScanQRManager:(YHAlbumScanQRManager *)albumManager didFinishPickingMediaWithResult:(NSString *)result{ NSString *content = result; // NetworkCenter *nc = [NetworkCenter shareManager]; // [nc checkScanContent:result completion:^(HuanYuBao_NetworkResult result, NSDictionary * _Nonnull responseDic) { // if (result == HuanYuBao_NetworkResultSuccess) { // [self.navigationController popViewControllerAnimated:YES]; // if (_delegate && [_delegate respondsToSelector:@selector(YHScanQRControllerManager:didFinishScingMediaWithResult:)]) { // [_delegate YHScanQRControllerManager:self didFinishScingMediaWithResult:responseDic]; // } // }else{ // ZZWHudHelper *hud = [ZZWHudHelper shareInstance]; // [hud showHudInSuperView:self.view withText:@"不支持该二维码" withType:HudModeTitle]; // dispatch_after(dispatch_time(DISPATCH_TIME_NOW,HudDuration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ // [hud hideHudInSuperView:self.view]; // }); // } // }]; } #pragma mark - YHScanQREngineManagerDelegate -(void)scanQREngineManager:(YHScanQREngineManager *)engineManager didOutputMetadaObjects:(NSArray *)metadaObjects{ if (_soundName == nil) { _soundName = @"sound.caf"; // NSString * path = [NSString stringWithFormat:@"Frameworks/YHScanQRTool.framework/%@", @"sound.caf"]; // _soundName = path; } [engineManager scanSuccessStopRunning]; [engineManager scanSuccessPlaySoundPath:_soundName]; [engineManager scanSuccessRemoveVideoPreviewFromSuperLayer]; NSString *content; if ([metadaObjects count] >0){ AVMetadataMachineReadableCodeObject * metadataObject = [metadaObjects objectAtIndex:0]; content = metadataObject.stringValue; } //直接代理返回 // PayMoneyController *vc = [PayMoneyController new]; // vc.content = content; // [self.navigationController pushViewController:vc animated:YES]; // NetworkCenter *nc = [NetworkCenter shareManager]; // [nc checkScanContent:content completion:^(HuanYuBao_NetworkResult result, NSDictionary * _Nonnull responseDic) { // if (result == HuanYuBao_NetworkResultSuccess) { // [self.navigationController popViewControllerAnimated:YES]; // if (_delegate && [_delegate respondsToSelector:@selector(YHScanQRControllerManager:didFinishScingMediaWithResult:)]) { // [_delegate YHScanQRControllerManager:self didFinishScingMediaWithResult:responseDic]; // } // // }else{ // ZZWHudHelper *hud = [ZZWHudHelper shareInstance]; // [hud showHudInSuperView:self.view withText:@"不支持该二维码" withType:HudModeTitle]; // dispatch_after(dispatch_time(DISPATCH_TIME_NOW,HudDuration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ // [hud hideHudInSuperView:self.view]; // }); // } // }]; } #pragma mark - UI - (YHScanQRView *)scanningView { if (!_scanningView) { _scanningView = [[YHScanQRView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height )]; //给属性设置默认值 if (_scanViewWidth == 0) { _scanViewWidth = scanBorderW; } if (_scanViewHeight == 0) { _scanViewHeight = scanBorderW; } if (_scanViewX == 0) { _scanViewX = (self.view.bounds.size.width - _scanViewWidth)/2; } if (_scanViewY == 0) { _scanViewY = (self.view.bounds.size.height - _scanViewHeight)/2; } if (_cornerLenght == 0) { _cornerLenght = 25; } if (_cornerWidth == 0) { _cornerWidth = 2.0; } if (_cornerColor == nil) { _cornerColor = [UIColor colorWithRed:85/255.0f green:183/255.0 blue:55/255.0 alpha:1.0]; } if (_viewBGColor == nil) { _viewBGColor = [UIColor blackColor]; } if (_borderColor == nil) { _borderColor = [UIColor whiteColor]; } if (_backgroundAlpha == 0) { _backgroundAlpha = 0.5; } if (_scanningImageName == nil) { NSString * path = [NSString stringWithFormat:@"Frameworks/YHScanQRTool.framework/%@", @"QRCodeScanningLine@3x.png"]; _scanningImageName = path; } if (_animationTimeInterval == 0) { _animationTimeInterval = 0.02; } // 传递属性值 _scanningView.cornerLenght = _cornerLenght; _scanningView.cornerWidth = _cornerWidth; _scanningView.cornerColor = _cornerColor; _scanningView.viewBGColor = _viewBGColor; _scanningView.borderColor = _borderColor; _scanningView.backgroundAlpha = _backgroundAlpha; _scanningView.scanningImageName = _scanningImageName; _scanningView.scanViewX = _scanViewX; _scanningView.scanViewY = _scanViewY; _scanningView.scanViewWidth = _scanViewWidth; _scanningView.scanViewHeight = _scanViewHeight; _scanningView.animationTimeInterval = _animationTimeInterval; } return _scanningView; } -(UILabel *) promptLabel{ if (!_promptLabel) { _promptLabel = [[UILabel alloc] init]; if (_isAddFlashLight == YES) { _promptLabel.frame = CGRectMake(0, _scanViewHeight+_scanViewY+50, self.view.bounds.size.width, 25); }else{ _promptLabel.frame = CGRectMake(0, _scanViewHeight+_scanViewY+15, self.view.bounds.size.width, 25); } _promptLabel.textAlignment = NSTextAlignmentCenter; if (_promptFont == nil) { _promptFont = [UIFont systemFontOfSize:16.0]; } if (_promptColor == nil) { _promptColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7]; } if (_promptContent == nil) { _promptContent = @"将二维码放入框内, 即可自动扫描"; } _promptLabel.font = _promptFont; _promptLabel.textColor = _promptColor; _promptLabel.text = _promptContent; } return _promptLabel; } #pragma mark - 私有方法 -(void) createFlashLightSender{ if (_isAddFlashLight == YES) { UIButton *lightBtn = [UIButton buttonWithType:UIButtonTypeCustom]; if (_scanViewHeight == 0) { _scanViewHeight = scanBorderW; } if (_scanViewY == 0) { _scanViewY = (self.view.bounds.size.height - _scanViewHeight)/2; } lightBtn.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-15, _scanViewY+_scanViewHeight+12 , 30, 32); if (_turnonName == nil) { NSString * path = [NSString stringWithFormat:@"Frameworks/YHScanQRTool.framework/%@", @"light_yellow.png"]; _turnonName = path; } if (_turnoffName == nil) { NSString * path = [NSString stringWithFormat:@"Frameworks/YHScanQRTool.framework/%@", @"light_gray.png"]; _turnoffName = path; } [lightBtn setImage:[UIImage imageNamed:_turnonName] forState:UIControlStateSelected]; [lightBtn setImage:[UIImage imageNamed:_turnoffName] forState:UIControlStateNormal]; [lightBtn addTarget:self action:@selector(turnLightBtnPressed:) forControlEvents:UIControlEventTouchUpInside]; lightBtn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; lightBtn.tag = 1; [self.scanningView addSubview:lightBtn]; } } -(void) createDoubleWithPichGesture{ if (_isTurnONGesture == YES) { UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTap:)]; doubleTapGesture.numberOfTapsRequired =2; doubleTapGesture.numberOfTouchesRequired =1; [self.view addGestureRecognizer:doubleTapGesture]; //捏合手势 UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; [self.view addGestureRecognizer:pinch]; if (_zoomMultiple == 0) { _zoomMultiple = 2.50; } } } #pragma mark - 点击事件以及手势事件 //手电筒切换 - (void)turnLightBtnPressed:(UIButton *)sender { UIButton *light = (UIButton *)sender; light.selected = !light.selected; self.manager.isTorch = light.selected; } //双击手势 - (void)handleDoubleTap:(UITapGestureRecognizer *)tap { if (_scaleViewMuilte > 1.1 ) { _scaleViewMuilte = 1.0; } else { _scaleViewMuilte = _zoomMultiple; } [CATransaction begin]; [CATransaction setAnimationDuration:0.2]; //放大焦距 if ([self.manager.nativeDevice lockForConfiguration:nil]) { [self.manager.nativeDevice setVideoZoomFactor:_scaleViewMuilte]; [self.manager.nativeDevice unlockForConfiguration]; } [CATransaction commit]; self.view.clipsToBounds=YES; self.view.layer.masksToBounds=YES; } //捏合手势的方法 - (void)pinch:(UIPinchGestureRecognizer *)recognizer { CGFloat scale = recognizer.scale; //放大 if (scale > 1.0) { _scaleViewMuilte += 0.2; if (_scaleViewMuilte >= _zoomMultiple) { _scaleViewMuilte = _zoomMultiple; } } //缩小 if (scale < 1.0) { _scaleViewMuilte -= 0.2; if (_scaleViewMuilte < 1.1) { _scaleViewMuilte = 1.0; } } recognizer.scale = 1.0; //放大焦距 if ([self.manager.nativeDevice lockForConfiguration:nil]) { [self.manager.nativeDevice setVideoZoomFactor:_scaleViewMuilte]; [self.manager.nativeDevice unlockForConfiguration]; } [CATransaction begin]; [CATransaction setAnimationDuration:0.2]; [CATransaction commit]; //把超出屏幕的部分裁减掉 self.view.clipsToBounds=YES; self.view.layer.masksToBounds=YES; } #pragma mark - 生命周期 -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:YES]; //移除定时器 [self.scanningView removeTimer]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; //添加定时器 [self.scanningView addTimer]; } - (void)dealloc { [self removeScanningView]; } - (void)removeScanningView { [self.scanningView removeTimer]; [self.scanningView removeFromSuperview]; } #pragma mark - 弹窗 -(void) createAlertViewWithMessage:(NSString *)message{ UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:(UIAlertControllerStyleAlert)]; UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) { }]; [alertC addAction:alertA]; [self presentViewController:alertC animated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end