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
  • 相关阅读:
    Oracle根据【日期】组,其他条件根据PIVOT行转列。使每个日期条件关联的其他数据只有一行。
    ORACLE数据库,数据量大,转移数据到备份表语句
    C#解析"a=1&b=2&c=3"字符串,微信支付返回字符串,替换<br>为&
    dataTable的数据,调试的时候点放大镜就看到了啊啊啊!
    Debug和Release 老程序啊 调试之前 区分一下啊
    FastReport.NET
    grpc 实现微服务生态笔记
    金木水火土
    shell 指令分析nginx 日志qps
    idea中使用tomcat 方式启动spring boot项目
  • 原文地址:https://www.cnblogs.com/ZMiOS/p/5498687.html
Copyright © 2011-2022 走看看