zoukankan      html  css  js  c++  java
  • 二维码的识别以及扫描界面的生成

    ViewController:

    #import "ViewController.h"
    #import "QRView.h"
    @interface ViewController () <QRViewDelegate>
    @property (weak, nonatomic) IBOutlet UILabel *valueLabel;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
       
        
        QRView *view = [[QRView alloc] init];
        
        view.frame = self.view.bounds;
        
        view.delegate = self;
        
        [self.view addSubview:view];
    }
    
    - (void)qrView:(QRView *)view didCompletedWithQRValue:(NSString *)qrValue
    {
        self.valueLabel.text = qrValue;
        [view removeFromSuperview];
    }
    
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end

    QRView.h:

    #import <UIKit/UIKit.h>
    
    
    @class QRView;
    
    @protocol QRViewDelegate <NSObject>
    
    - (void) qrView:(QRView *) view didCompletedWithQRValue:(NSString *) qrValue;
    
    
    @end
    
    
    @interface QRView : UIView
    
    @property (nonatomic, weak) id<QRViewDelegate> delegate;
    
    @end

    QRView.m

    #import "QRView.h"
    #import <AVFoundation/AVFoundation.h>
    /**
     *  具备二维码扫描的功能
     */
    @interface QRView () <AVCaptureMetadataOutputObjectsDelegate>
    
    /**
     *  背景框
     */
    @property (nonatomic, weak) UIImageView *bgView;
    /**
     *  线
     */
    @property (nonatomic, weak) UIImageView *lineView;
    
    /**
     *  session
     */
    
    @property (nonatomic, strong) AVCaptureSession *session;
    
    
    @end
    
    
    @implementation QRView
    
    /**
     *  设置QRView的layer是AVCaptureVideoPreviewLayer
     */
    + (Class)layerClass
    {
        return [AVCaptureVideoPreviewLayer class];
    }
    
    /**
     *  使用纯代码创建View时候会调用该方法
     */
    - (instancetype) initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame:frame]) {
            [self setUp];
        }
        return self;
    }
    
    /**
     *使用storyboard或xib创建View时候会调用该方法
     */
    - (instancetype) initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super initWithCoder:aDecoder]) {
            [self setUp];
        }
        return self;
    }
    
    - (void) setUp
    {
        UIImageView *bgView = [[UIImageView alloc] init];
        [self addSubview:bgView];
        self.bgView = bgView;
        
        UIImageView *lineView = [[UIImageView alloc] init];
        [self addSubview:lineView];
        self.lineView = lineView;
        
    //  设置数据
        self.bgView.image = [UIImage imageNamed:@"pick_bg"];
        self.lineView.image = [UIImage imageNamed:@"line"];
        
        [self configQR];
    }
    
    /**
     *  配置解析二维码
     */
    - (void) configQR
    {
    //  创建输入对象
    //  默认是后置摄像头
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        NSError *error = nil;
        
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
        
        if(error){
            NSLog(@"%@",error);
            return;
        }
        
    //  创建输出设备
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
        
    //  创建session
        self.session = [[AVCaptureSession alloc] init];
    //  连接设备
        if ([self.session canAddInput:input]) {
            [self.session addInput:input];
        }
        
        if ([self.session canAddOutput:output]) {
            [self.session addOutput:output];
        }
        
    //  设置输出对象的元数据类型
        output.metadataObjectTypes = output.availableMetadataObjectTypes;
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        
       AVCaptureVideoPreviewLayer *layer = (AVCaptureVideoPreviewLayer *)self.layer;
        layer.session = self.session;
        
    // 开始运行session
        [self.session startRunning];
    }
    
    /**
     *  当输出对象解析到相应地内容的时候,就会调用该方法
     */
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
    {
        AVMetadataMachineReadableCodeObject *obj = [metadataObjects firstObject];
        
        if (obj.stringValue.length != 0) {
            if ([self.delegate respondsToSelector:@selector(qrView:didCompletedWithQRValue:)]) {
                [self.delegate qrView:self didCompletedWithQRValue:obj.stringValue];
            }
            [self.session stopRunning];
        }
    }
    
    
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        CGSize size = self.bounds.size;
        
        CGFloat bgW = 200;
        CGFloat bgH = 200;
        CGFloat bgX = (size.width - bgW) * 0.5;
        CGFloat bgY = (size.height - bgH) * 0.5;
    //  背景的位置
        self.bgView.frame = CGRectMake(bgX, bgY, bgW, bgH);
    //  线的frame
        self.lineView.frame = CGRectMake(bgX, bgY, bgW, 2);
        
    //  使用核心动画
        [self.lineView.layer removeAnimationForKey:@"positionAnimation"];
    
        CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
        
        positionAnimation.fromValue = @(bgY);
        
        positionAnimation.toValue = @(CGRectGetMaxY(self.bgView.frame));
        
        positionAnimation.duration = 2;
        
        positionAnimation.repeatCount = NSIntegerMax;
        
        [self.lineView.layer addAnimation:positionAnimation forKey:@"positionAnimation"];
    }
    
    
    @end
    QRView.m
  • 相关阅读:
    查看mysql版本的四种方法及常用命令
    newInstance和new的区别(good)
    Citrix 服务器虚拟化之六 Xenserver虚拟机创建与快照
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 前缀表达式
    Java实现 蓝桥杯 算法训练 前缀表达式
  • 原文地址:https://www.cnblogs.com/ZMiOS/p/5498687.html
Copyright © 2011-2022 走看看