// // QRViewController.m // QRWeiXinDemo // // Created by lovelydd on 15/4/25. // Copyright (c) 2015年 lovelydd. All rights reserved. // #import "QRViewController.h" #import #import "QRView.h" #import "QRUtil.h" @interface QRViewController () @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) UIButton *backBtn; @property (nonatomic, strong) QRView *qrView; @property (nonatomic, copy) ScanCompleteBlock scanCompleteBlock; @property (nonatomic, copy, readwrite) NSString *urlString; /** * 提示lebe */ @property (nonatomic,strong) UILabel *Titlelabe; /** *计时器 */ @property (strong, nonatomic) CADisplayLink *link; /** * 指示线 */ @property (strong, nonatomic) UIImageView *instructionsLine; /** *用于记录scrollLine的上下循环状态 */ @property (assign, nonatomic) BOOL up; @end @implementation QRViewController #pragma mark - Life Cycle - (void)viewDidLoad { [super viewDidLoad]; //计时器添加到循环中去 _up = YES; [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; [self defaultConfig]; //初始化配置,主要是二维码的配置 [self configUI]; [self updateLayout]; } - (void)defaultConfig { [self startRunning]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (![_session isRunning]) { [self startRunning]; } } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self stopRunning]; } - (void)configUI { [self.view addSubview:self.qrView]; [self.view addSubview:self.backBtn]; [self.view addSubview:self.Titlelabe]; [self.view addSubview:self.instructionsLine]; } - (void)updateLayout { _qrView.center = CGPointMake([QRUtil screenBounds].size.width / 2, [QRUtil screenBounds].size.height / 2); //修正扫描区域 CGFloat screenHeight = self.view.frame.size.height; CGFloat screenWidth = self.view.frame.size.width; CGRect cropRect = CGRectMake((screenWidth - self.qrView.transparentArea.width) / 2, (screenHeight - self.qrView.transparentArea.height) / 2, self.qrView.transparentArea.width, self.qrView.transparentArea.height); [_output setRectOfInterest:CGRectMake(cropRect.origin.y / screenHeight, cropRect.origin.x / screenWidth, cropRect.size.height / screenHeight, cropRect.size.width / screenWidth)]; } - (void)pop:(UIButton *)button { [self dismissViewControllerAnimated:YES completion:^{ if (self.cancelScanBlock) { self.cancelScanBlock(); } }]; } #pragma mark - Public Method -(instancetype)initWithScanCompleteHandler:(ScanCompleteBlock)scanCompleteBlock { self = [super init]; if (self) { _scanCompleteBlock = scanCompleteBlock; } return self; } - (void)startRunning { _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; // Input _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil]; // Output _output = [[AVCaptureMetadataOutput alloc]init]; [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; // Session _session = [[AVCaptureSession alloc]init]; [_session setSessionPreset:AVCaptureSessionPresetHigh]; if ([_session canAddInput:self.input]) { [_session addInput:self.input]; } if ([_session canAddOutput:self.output]) { [_session addOutput:self.output]; } AVCaptureConnection *outputConnection = [_output connectionWithMediaType:AVMediaTypeVideo]; outputConnection.videoOrientation = [QRUtil videoOrientationFromCurrentDeviceOrientation]; // 条码类型 AVMetadataObjectTypeQRCode _output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode]; // Preview _preview =[AVCaptureVideoPreviewLayer layerWithSession:_session]; _preview.videoGravity =AVLayerVideoGravityResize; _preview.frame =[QRUtil screenBounds]; [self.view.layer insertSublayer:_preview atIndex:0]; _preview.connection.videoOrientation = [QRUtil videoOrientationFromCurrentDeviceOrientation]; [_session startRunning]; } - (void)stopRunning { [_preview removeFromSuperlayer]; [_session stopRunning]; } //#pragma mark QRViewDelegate //-(void)scanTypeConfig:(QRItem *)item { // // if (item.type == QRItemTypeQRCode) { // _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode]; // // } else if (item.type == QRItemTypeOther) { // // _output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code, // AVMetadataObjectTypeEAN8Code, // AVMetadataObjectTypeCode128Code, // AVMetadataObjectTypeQRCode, // AVMetadataObjectTypeQRCode]; // } //} #pragma mark AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { NSString *stringValue = @""; if ([metadataObjects count] >0) { //停止扫描 [_session stopRunning]; AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0]; stringValue = metadataObject.stringValue; } self.urlString = stringValue; NSLog(@" 扫描后的url是:%@",stringValue); if (self.scanCompleteBlock) { self.scanCompleteBlock(stringValue); } } #pragma mark - Getter and Setter -(UIButton *)backBtn { if (!_backBtn) { _backBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _backBtn.frame = CGRectMake(50, ScreenHeight-80, 100, 50); [_backBtn setTitle:@"取消扫描" forState:UIControlStateNormal]; [_backBtn addTarget:self action:@selector(pop:) forControlEvents:UIControlEventTouchUpInside]; } return _backBtn; } #pragma mark -设置扫描范围 -(QRView *)qrView { if (!_qrView) { CGRect screenRect = [QRUtil screenBounds]; _qrView = [[QRView alloc] initWithFrame:screenRect]; _qrView.transparentArea = CGSizeMake(400, 400); _qrView.backgroundColor = [UIColor clearColor]; _qrView.delegate = self; } return _qrView; } #pragma mark -提示文本 - (UILabel *)Titlelabe { if (!_Titlelabe) { _Titlelabe = [[UILabel alloc]initWithFrame:CGRectMake((ScreenWidth-400)/2, 120, 400, 50)]; _Titlelabe.text = @"将条形码/二维码放入框内,即可自动扫描"; _Titlelabe.font = [UIFont systemFontOfSize:20]; _Titlelabe.textColor = [UIColor whiteColor]; } return _Titlelabe; } #pragma mark -指示器 - (UIImageView *)instructionsLine { if (!_instructionsLine) { _instructionsLine = [[UIImageView alloc]initWithFrame:CGRectMake((ScreenWidth - self.qrView.transparentArea.width) / 2 +20, (ScreenHeight - self.qrView.transparentArea.height) / 2 +20, self.qrView.transparentArea.width-40, 15)]; _instructionsLine.image = TCImage(@"圆角矩形-5"); } return _instructionsLine; } #pragma mark -指示器动画 - (CADisplayLink *)link { if (!_link) { _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(LineAnimation)]; } return _link; } #pragma mark - 线条运动的动画 - (void)LineAnimation { if (_up == YES) { CGFloat y = self.instructionsLine.frame.origin.y; y += 4; CGRect frame = self.instructionsLine.frame; frame.origin.y = y; self.instructionsLine.frame = frame; if (y >= (ScreenHeight - self.qrView.transparentArea.height) / 2 +self.qrView.transparentArea.height-20) { _up = NO; } }else{ CGFloat y = self.instructionsLine.frame.origin.y; y -= 4; CGRect frame = self.instructionsLine.frame; frame.origin.y = y; self.instructionsLine.frame = frame;; if (y <= (ScreenHeight - self.qrView.transparentArea.height) / 2 +20) { _up = YES; } } } @end