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 中二维码扫描的更多相关文章
- iOS 中二维码扫描(zxingObjc和原生)
对于网上的第三方 ZXingObjC,自我感觉是对原生的AVFoundation中关于二维码部分的一个封装,大致看看ZXingObjC的内部实现其事和原生的实现相似的,里面都用到了AVFoundati ...
- Ios二维码扫描(系统自带的二维码扫描)
Ios二维码扫描 这里给大家介绍的时如何使用系统自带的二维码扫描方法和一些简单的动画! 操作步骤: 1).首先你需要搭建UI界面如图:下图我用了俩个imageview和一个label 2).你需要在你 ...
- iOS二维码扫描IOS7系统实现
扫描相关类 二维码扫描需要获取摄像头并读取照片信息,因此我们需要导入系统的AVFoundation框架,创建视频会话.我们需要用到一下几个类: AVCaptureSession 会话对象.此类作为硬件 ...
- iOS - 二维码扫描和应用跳转
序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar.使用时集成麻烦, ...
- ios二维码扫描插件,适配当前主流扫描软件,自定义扫描界面。
二维码介绍: 二维码(QR(Quick Response)code),又称二维条码,最早起源于日本. 它是用特定的几何图形按一定规律在平面(二维方向)上分布的黑白相间的图形,是所有信息 ...
- iOS中二维码的生成与使用(入门篇)
这里简单总结一下关于二维码的扫描与生成,用的是原生的AVFoundation框架,其实这个框架目前功能还是够用的,不过这里推荐一个二维码扫描的第三方(face++),网址就不贴了,直接度娘就OK,里面 ...
- iOS二维码扫描的实现(Swift)
随着二维码的普遍使用,二维码扫描也成为了很多app的一个基本功能,本篇主要来介绍一下如何实现一个简单的二维码扫描功能.本文使用了XCode自带的AVFoundation 库,利用Swfit语言实现. ...
- ios中二维码的使用之二: 二维码的扫描
二维码的扫描: 1,导入支持框架,<AVFoundation/AVFoundation.h> 2 ,扫描:
- ios中二维码的使用之一: 二维码的生成
iOS在7之后,具备了原生的二维码生成API; 生成二维码的准备: #import <CoreImage/CoreImage.h> 导入框架: 开始生成: //1- 创建过滤器 CIFi ...
随机推荐
- 解决两台centos虚拟机Telnet服务无法联机的问题
关闭防火墙 [root@localhost ~]# service iptables stopiptables: Flushing firewall rules: ...
- 远程方法调用(RMI)原理与示例
RMI介绍 远程方法调用(RMI)顾名思义是一台机器上的程序调用另一台机器上的方法.这样可以大致知道RMI是用来干什么的,但是这种理解还不太确切.RMI是Java支撑分布式系统的基石,例如著名的EJB ...
- 领域实体框架Rafy2 发布了
在2009年我在codeplex发布了1.0版本OpenExpressApp,下载地址:http://openexpressapp.codeplex.com/.OEA 1.0 作为我十多年开发工作的一 ...
- 浅谈Mysql的MyIsam存储类型
前两年的工作,用NoSql多一些!最近进入了传统的软件开发公司,开始使用Mysql多了!不过对于我这种ABC级别的人来说,还是好好看书吧! 我常常觉得,如果我们不是明白原理,而只是知道一些概念,或者说 ...
- 重构第31天 使用多态替代条件语句( Replace conditional with Polymorphism)
理解:本文中的”使用多态代替条件判断”是指如果你需要检查对象的类型或者根据类型执行一些操作时,一种很好的办法就是将算法封装到类中,并利用多态性进行抽象调用. 详解:本文展示了面向对象编程的基础之一“多 ...
- 划分树---Feed the dogs
POJ 2761 Description Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to fee ...
- PHP json编码遇到的问题
今天遇到了json编码解码之后中文消失的问题,一探究竟,写下这篇文章 PHP中提供了json_encode 和json_decode 这对函数 将PHP中 值转化成 字符串,但是遇到中文的时候,很容 ...
- Android性能优化之一:ViewStub
ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Android开发人员基本上都听说过,但是真正用的可能不多. ViewStub可以理解成一个非常轻量级的Vie ...
- 备份一张iPhone拍照写入exif中的orientation图片
- Ansible用于网络设备管理 part 1 Jinja2 YAML初窥
这一次的实验内容依然来自Kirk Byers的博客,源地址在https://pynet.twb-tech.com/blog/python/paramiko-ssh-part1.html 但是,这次实验 ...