美文网首页
自定义扫描二维码界面

自定义扫描二维码界面

作者: Treey_Ahao | 来源:发表于2018-02-24 11:31 被阅读0次

    由于项目需求,程序需要实现自定义界面二维码扫描功能,所以我找了一下系统二维码扫描的方法。

    下面是我封装代码:
    .h里的代码:

    #import <Foundation/Foundation.h>
    #import <AVFoundation/AVFoundation.h>
    @interface ZHSearchScanHelper : NSObject <AVCaptureMetadataOutputObjectsDelegate>
    
    @property (strong, nonatomic) void(^ScanBlock)(NSString * str);
    
    /* 输入输出中间桥梁 */
    @property (strong, nonatomic) AVCaptureSession           * session;
    /* 设备 */
    @property (strong, nonatomic) AVCaptureDevice            * device;
    /* 采集设备输入 */
    @property (strong, nonatomic) AVCaptureDeviceInput       * input;
    /* 捕捉元数据输出 */
    @property (strong, nonatomic) AVCaptureMetadataOutput    * output;
    /* 扫描的View */
    @property (strong, nonatomic) UIView                     * scanView;
    /* 捕捉视频预览层 */
    @property (strong, nonatomic) AVCaptureVideoPreviewLayer * layer;
    /* 图层父类 */
    @property (strong, nonatomic) UIView                     * superView;
    
    
    /* 为了做扫描动画的定时器 */
    @property (strong, nonatomic) NSTimer                    * timer;
    /* 扫描动画的横线 */
    @property (strong, nonatomic) UIImageView                * lineImage;
    
    +(instancetype)manager;
    
    -(void)startRunning;
    -(void)stopRunning;
    -(void)stopSetView;
    -(void)showLayer:(UIView *)viewController;
    -(void)setscanningRect:(CGRect)scanRect scanView:(UIView *)scanView;
    
    @end
    

    .m里的代码:

    +(instancetype)manager
    {
        static ZHSearchScanHelper * manager = nil;
        static dispatch_once_t once_Token;
        dispatch_once(&once_Token, ^{
            manager = [[ZHSearchScanHelper alloc]init];
        });
        return manager;
    }
    
    
    -(instancetype)init
    {
        if (self = [super init]) {
        
            // Session初始化
            _session = [[AVCaptureSession alloc]init];
            // 高质量采样率
            [_session setSessionPreset:AVCaptureSessionPresetHigh];
            
            // 避免模拟器运行崩溃
            if (!TARGET_IPHONE_SIMULATOR) {
                
                // Device
                _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
                
                // Input 输入流
                _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];
                if ([_session canAddInput:_input])
                {
                    [_session addInput:_input];
                }
                
                // Output 输出流
                _output = [[AVCaptureMetadataOutput alloc]init];
                // 设置代理 在主线程刷新
                [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
                if ([_session canAddOutput:_output])
                {
                    [_session addOutput:_output];
                }
                
                // 设置扫码支持的编码格式
                // 条码类型 AVMetadataObjectTypeQRCode
                _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode,
                                               AVMetadataObjectTypeEAN13Code,
                                               AVMetadataObjectTypeEAN8Code,
                                               AVMetadataObjectTypeCode128Code];
                
                // 更新界面
                _layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
                _layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            }
        }
        return self;
    }
    
    
    #pragma mark 方法
    // 开始
    -(void)startRunning
    {
        if (!TARGET_IPHONE_SIMULATOR) {
            [_session startRunning];
        }
    }
    
    
    // 停止
    -(void)stopRunning
    {
        if (!TARGET_IPHONE_SIMULATOR) {
            [_session stopRunning];
        }
    }
    
    
    #pragma mark delegate
    -(void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection
    {
        NSString *stringValue;
        
        if (metadataObjects.count > 0) {
            
            AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
            stringValue = metadataObject.stringValue;
            // 传值
            if (self.ScanBlock) {
                self.ScanBlock(stringValue);
            }
            // 停止
            [self stopSetView];
            
            NSLog(@"%@",stringValue);
        }
    }
    
    
    /* 停止设置 */
    -(void)stopSetView
    {
        // 结束
        [_session stopRunning];
        // 移除界面
        for (UIView * view in self.superView.subviews) {
            [view removeFromSuperview];
        }
        // 计时器停止
        [_timer invalidate];
        _timer = nil;
    }
    
    
    /*
     设置扫描区域
     @param scanRect 扫描范围
     @param scanRect 扫描框
     */
    -(void)setscanningRect:(CGRect)scanRect scanView:(UIView *)scanView
    {
        CGFloat x,y,width,height;
        
        x = scanRect.origin.y / _layer.frame.size.height;
        y = scanRect.origin.x / _layer.frame.size.width;
        width = scanRect.size.height / _layer.frame.size.height;
        height = scanRect.size.width / _layer.frame.size.width;
        
        _output.rectOfInterest = CGRectMake(x, y, width, height);
        
        self.scanView = scanView;
        if (self.scanView) {
            self.scanView.frame = scanRect;
            if (self.superView) {
                [self.superView addSubview:_scanView];
                [self setCover:_scanView];
            }
        }
    }
    
    
    /* 添加图层 */
    -(void)showLayer:(UIView *)viewController
    {
        _superView = viewController;
        _layer.frame = _superView.layer.frame;
        [_superView.layer insertSublayer:_layer atIndex:0];
    }
    
    
    //    167 167 167   32   居上50
    /* 设置覆盖层界面 */
    -(void)setCover:(UIView *)view
    {
        UIColor * color = [UIColor blackColor];
        
        UIView * view_1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.superView.bounds.size.width, view.frame.origin.y)];
        view_1.backgroundColor = color;
        view_1.alpha = 0.8;
        [self.superView addSubview:view_1];
        
        UIView * view_2 = [[UIView alloc]initWithFrame:CGRectMake(0, view.frame.origin.y+view.frame.size.height, self.superView.bounds.size.width, self.superView.bounds.size.height-(view.frame.origin.y+view.frame.size.height))];
        view_2.backgroundColor = color;
        view_2.alpha = 0.8;
        [self.superView addSubview:view_2];
        
        UIView * view_3 = [[UIView alloc]initWithFrame:CGRectMake(0, view.frame.origin.y, view.frame.origin.x, view.frame.size.height)];
        view_3.backgroundColor = color;
        view_3.alpha = 0.8;
        [self.superView addSubview:view_3];
        
        UIView * view_4 = [[UIView alloc]initWithFrame:CGRectMake(view.frame.origin.x+view.frame.size.width, view.frame.origin.y, view.frame.origin.x, view.frame.size.height)];
        view_4.backgroundColor = color;
        view_4.alpha = 0.8;
        [self.superView addSubview:view_4];
        
        UIImageView * imageV = [[UIImageView alloc]initWithFrame:view.bounds];
        imageV.image = [UIImage imageNamed:@"fo_bi"];
        imageV.backgroundColor = [UIColor clearColor];
        [view addSubview:imageV];
        
        UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, view.frame.origin.y+view.frame.size.height+50*kScale, self.superView.bounds.size.width, 50*kScale)];
        label.text = @"将二维码/条码放入框内,即可自动扫描";
        label.textColor = JMColor(167, 167, 167);
        label.font = [UIFont systemFontOfSize:32*kScale];
        label.textAlignment = NSTextAlignmentCenter;
        label.backgroundColor = [UIColor clearColor];
        [self.superView addSubview:label];
        
        _lineImage = [[UIImageView alloc]initWithFrame:CGRectMake(20*kScale, 30*kScale, view.bounds.size.width-40*kScale, 16*kScale)];
        _lineImage.image = [UIImage imageNamed:@"green_line"];
        _lineImage.backgroundColor = [UIColor clearColor];
        [view addSubview:_lineImage];
        
        NSTimer *timer = [NSTimer timerWithTimeInterval:2.5 target:self selector:@selector(timerLineChangeFrame:) userInfo:@(YES) repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        self.timer = timer;
    }
    
    
    -(void)timerLineChangeFrame:(NSTimer *)timer
    {
        [self animated];
    }
    
    
    #pragma mark 动画
    - (void)animated
    {
        _lineImage.frame = CGRectMake(20*kScale, 30*kScale, _scanView.bounds.size.width-40*kScale, 16*kScale);
        [UIView animateWithDuration:2.5 animations:^{
            [UIView setAnimationCurve:UIViewAnimationCurveLinear];
            _lineImage.frame = CGRectMake(20*kScale, _scanView.bounds.size.height-30*kScale-16*kScale, _lineImage.superview.bounds.size.width-40*kScale, 8*kScale);
        }];
    }
    

    在父类使用:
    设置扫描界面

    -(void)setScanView
    {
        WeakSelf(weakSelf);
        CGSize windowSize = [UIScreen mainScreen].bounds.size;
        CGSize scanSize = CGSizeMake(windowSize.width * 3/5, windowSize.width *3/5);
        CGRect scanRect = CGRectMake((windowSize.width-scanSize.width)/2, 300*kScale, scanSize.width, scanSize.height);
        UIView * scanRectView = [UIView new];
        scanRectView.layer.borderColor = [UIColor clearColor].CGColor;
        scanRectView.layer.borderWidth = 0;
    
        [[ZHSearchScanHelper manager] showLayer:self.view];
        [[ZHSearchScanHelper manager] setscanningRect:scanRect scanView:scanRectView];
        [[ZHSearchScanHelper manager] setScanBlock:^(NSString *scanResult)
        {
            NSLog(@"---%@", scanResult);
            
            // 根据自己的需要对扫描结果进行处理
            // 获取数据
            [weakSelf getProductionData:scanResult];
    
        }];
        [[ZHSearchScanHelper manager] startRunning];
    }
    

    相关文章

      网友评论

          本文标题:自定义扫描二维码界面

          本文链接:https://www.haomeiwen.com/subject/namxxftx.html