iOS中二维码扫描

随着微信的大量推广,越来越多的人会在生活中用到二维码这一个方便大家的功能。

因此,很多的app中也逐渐的都加入了二维码这个元素,今天先给大家介绍一下iOS7后系统自带自己可以手动设计的二维码扫描。

QRCodeViewController这个类是实现二维码扫描创建的类,今天我写的这个类似于官方文档中的实现,可以直接扫描二维码跳转到当前二维码对应的链接,如果是应用的话,会跳转到appStore中对应的应用详情。

除了这个,现在用的比较多的还有ZBarSDK等三方库,实现的效果要比自己写的这个漂亮,后面有机会的话,我会介绍一下ZBarSDK的用法以及经常遇到的问题和解决方法。

下面是主要实现:

#import "QRCodeViewController.h"

#import <AVFoundation/AVFoundation.h>

@interface QRCodeViewController () <AVCaptureMetadataOutputObjectsDelegate>

{

    BOOL _isReading;

}

@property (weak, nonatomic) IBOutlet UIView *ShowView;

@property (nonatomic,strong) UIView *boxView;

//@property (nonatomic,assign) BOOL *isReading;

@property (nonatomic,strong) CALayer *scanLayer;

@property (nonatomic,strong) UILabel *urlLabel;

-(BOOL)startReading;

-(void)stopReading;

//捕捉会话

@property (nonatomic,strong) AVCaptureSession *captureSession;

//展示layer

@property (nonatomic,strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;

@end

@implementation QRCodeViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];

    btn.frame = CGRectMake(0, 30, 50, 30);

    [btn setImage:[UIImage imageNamed:@"return@2x"] forState:UIControlStateNormal];

    [btn addTarget:self action:@selector(leftClicked) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];

    _captureSession = nil;

    //_isReading = NO;

    [self startReading];

}

-(void)leftClicked{

    [self dismissViewControllerAnimated:YES completion:nil];

}

-(BOOL)startReading{

    NSError *error = nil;

    //1.初始化捕捉设备(AVCaptureDevice),类型为AVMediaTypeVideo

    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    //2.用captureDevice创建输入流

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];

    if (!input) {

        NSLog(@"%@",[error localizedDescription]);

        return NO;

    }

    //3.创建媒体数据输出流

    AVCaptureMetadataOutput *captureMedataOutput = [[AVCaptureMetadataOutput alloc]init];

    //4.实例化捕捉会话

    _captureSession = [[AVCaptureSession alloc]init];

    //4.1将输入流添加到会话

    [_captureSession addInput:input];

    //4.2将媒体输出流添加到会话中

    [_captureSession addOutput:captureMedataOutput];

    //5.创建串行队列,并将媒体输出流添加到队列中

    dispatch_queue_t dispatchQueue;

    dispatchQueue = dispatch_queue_create("myQueue", NULL);

    //5.1设置代理

    [captureMedataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];

    //5.2设置输出媒体数据类型为QRCode

    [captureMedataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];

    //6.实例化预览图层

    _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:_captureSession];

    //7.设置预览图层填充方式

    [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

    //8.设置图层的frame

    [_videoPreviewLayer setFrame:_ShowView.layer.bounds];

    //9.将图层添加到预览view的图层上

    [_ShowView.layer addSublayer:_videoPreviewLayer];

    //10.设置扫描范围

    captureMedataOutput.rectOfInterest = CGRectMake(0.2f, 0.2f, 0.8f, 0.8f);

    //10.1. 设置扫描框

    _boxView = [[UIView alloc]initWithFrame:CGRectMake(_ShowView.bounds.size.width * 0, _ShowView.bounds.size.height*0, _ShowView.bounds.size.width, _ShowView.bounds.size.height)];

    _boxView.layer.borderColor = [UIColor greenColor].CGColor;

    _boxView.layer.borderWidth = 1.0f;

    [_ShowView addSubview:_boxView];

    //10.2扫描线

    _scanLayer = [[CALayer alloc]init];

    _scanLayer.frame = CGRectMake(0, 0, _boxView.bounds.size.width, 2);

    _scanLayer.backgroundColor = [UIColor cyanColor].CGColor;

    [_boxView.layer addSublayer:_scanLayer];

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(moveScanLayer:) userInfo:nil repeats:YES];

    [timer fire];

    //11.开始扫描

    [_captureSession startRunning];

    return 1;

}

-(void)moveScanLayer:(NSTimer *)timer{

    CGRect frame = _scanLayer.frame;

    if (_boxView.frame.size.height <= _scanLayer.frame.origin.y) {

        frame.origin.y = 0;

        _scanLayer.frame = frame;

    }

    else{

        frame.origin.y += 5;

        [UIView animateWithDuration:0.1 animations:^{

            _scanLayer.frame = frame;

        }];

    }

}

-(void)stopReading{

//    [_captureSession stopRunning];

//    _captureSession = nil;

//    [_scanLayer removeFromSuperlayer];

//    [_videoPreviewLayer removeFromSuperlayer];

}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{

    //判断是否有数据

    if (metadataObjects !=nil && [metadataObjects count]>0) {

        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];

        //判断回传的数据类型

        if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {

            [self performSelectorOnMainThread:@selector(setUrl:) withObject:[metadataObj stringValue] waitUntilDone:NO];

            //[[UIApplication sharedApplication] openURL:url];

            [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];

            _isReading = NO;

        }

    }

}

-(void)setUrl:(NSString *)text{

    NSURL *url = [NSURL URLWithString:text];

    [[UIApplication sharedApplication] openURL:url];

}

更多相关文章
  • IOS二维码扫描IOS7系统实现
    扫描相关类 二维码扫描需要获取摄像头并读取照片信息,因此我们需要导入系统的AVFoundation框架,创建视频会话.我们需要用到一下几个类: AVCaptureSession 会话对象.此类作为硬件设备输入输出信息的桥梁,承担实时获取设备数据的责任 AVCaptureDeviceInput 设备输 ...
  • 这篇博客是对上篇博客的补充,内容较少. 由于二维码扫描需要在真机上测试本人比较烂就不做效果图了. 下面是代码(代码中已经写了很清楚的注释) ,, self.view.frame.size.width, ); [self.view.layer addSublayer:layer]; //开始扫描 [s ...
  • 随着二维码的普遍使用,二维码扫描也成为了很多app的一个基本功能,本篇主要来介绍一下如何实现一个简单的二维码扫描功能.本文使用了XCode自带的AVFoundation 库,利用Swfit语言实现. 实现的步骤如下: 1.获取视频设备(Video) 在二维码扫描中,我们的输入流是视频.我们需要ena ...
  •   扫描二维码的开源库有很多如 ZBar.ZXing等 ZBar的使用方法: 下载ZBar SDK 地址https://github.com/bmorton/ZBarSDK ZBarSDK是一个开源的SDK,该SDK实现了识别和读取各种条形码,包括EAN-13/UPC-A, UPC-E, EAN-8 ...
  • 做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framework框架到你工程中build phase的"Link Binary With Librar ...
  • 这几天刚好将本人高仿新浪微博的事情进行一个阶段性的tag,在此也将这个项目在实现二维码扫描这个功能来做一个简要的记录.关于高仿新浪微博的源代码,本人已经将全部代码托管到github,地址在这里.欢迎大家指正.接下来我们来看看QRCode扫描的实现. 关于二维码的扫描,网上说的最多的框架莫过于ZBar ...
  • iOS自带二维码扫描功能的实现
    #自从iOS7以后中新增了二维码扫描功能.因此可以在不借助第三方类库的情况下简单的写出二维码的扫描功能: 原生的二维码扫描功能在AVFoundation框架下,所以在使用原生的二维码扫描功能时要先导入AVFoundation框架: 然后添加以下属性: <pre><code>@ ...
  • 关于二维码扫描有不少优秀第三方库: ZBar SDK 里面有详细的文档,相应介绍也非常多,如: #import <AVFoundation/AVFoundation.h> static const char *kScanQRCodeQueueName = "ScanQRCode ...
一周排行
  • Axis2是目前比较流行的WebService引擎.WebService被应用在很多不同的场景.例如,可以使用WebService来发布服务端 Java类的方法,以便使用不同的客户端进行调用.这样可以有效地集成多种不 ...
  • Cocos2d-x实战工具卷上线了-源码-样章-感谢大家的支持
    <Cocos2d-x实战 工具卷>上线了感谢大家一直以来的支持!各大商店均开始 ...
  • 距离矢量(Distance Vector)说法是因为路由是以矢量(距离.方向)的方式通告出去的,其中距离是根据度量定义的,方向是根据下一跳路由器定义的.因此,满足距离矢量路由选择协议的条件要有两条,缺一不可: 1.给 ...
  • rpm包安装MySQL5.7MySQL5.7.9已经发布,本文介绍如何用rpm包安装MySQL5.7,操作系统基于centos6.6,最小化安装.下载MySQLwget http://mirrors.sohu.com ...
  • python生成二维码,常用的模块有pyqrencode和qrcode.一.用pyqrencode模块生成二维码安装pyqrencode模块很复杂,依赖的东西也比较多,经过测试总结以下安装过程:1.下载Cython: ...
  •  今天在一个QQ群中,有人说到这个一个面试题:一头母牛在3—10岁的时候每年可以生一头小牛,生公牛和母牛的比率是50%,在牛12岁的时候就送入屠宰场买了.现在有一个农夫有1头1岁大的母牛,在母牛3岁的时候就送到附近的 ...
  • GC垃圾回收
    永久代不在堆内存里 Java堆内存(heap):     --是 JVM 用于分配 Jav ...
  • DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序接口). Document类型 文档的子节点 虽然DOM标准规定Document节点的子节点可以是DocumentType,Element,Pro ...
  • 转自:http://www.cdtarena.com/javapx/201307/9171.html Date类在JDK1.0中,Date类是唯一的一个代表时间的类,但是由于Date类不便于实现国际化,所以从JDK1 ...
  • 1.前言目前正在涉足云计算IaaS工作,虚拟化是IaaS的重要部分,因此这段时间对各个虚拟机化技术和工具进行研究,研究的目的不仅仅是为了会使用这个工具,而是通过研究了解技术的实现机制和原理,即知其然也要知其所以然,本 ...