ios二维码扫描插件,适配当前主流扫描软件,自定义扫描界面。
二维码介绍:
二维码(QR(Quick Response)code),又称二维条码,最早起源于日本。
它是用特定的几何图形按一定规律在平面(二维方向)上分布的黑白相间的图形,是所有信息数据的一把钥匙。
二维码是一种比一维码更高级的条码格式。一维码只能在一个方向(一般是水平方向)上表达信息,
而二维码在水平和垂直方向都可以存储信息。一维码只能由数字和字母组成,而二维码能存储汉字、数字和图片等信息,
因此二维码的应用领域要广得多。
二维码需求:
开发一款二维码扫描插件,具有扫描大众二维码的能力,能够识别二维码当中包含的网页链接以及文本信息。对网页链接跳转safari浏览器(但是对自己公司的连接要求在app内部内置浏览器)。对扫描的内容弹出提示框。并且让别的app扫描我们自己的二维码的时候要跳转到appstore下载。
需求确认:
二维码算法自己写?不现实。开发周期太长,那就使用第三方那个库QR(Quick Response)code ZBarSDK,读取信息的时候首先应该判断是不是网页连接,考虑用正则表达式对扫描的结果进行过滤。对于内置浏览器使用webview控件。弹出提示框使用UIAlertView太麻烦,而且不好用,所以采用开源第三方库BlockAlertActionSheet,BlockAlertActionSheet使用block做的一款具有提示功能类似UIAlertView UIActionSheet等控件。很强大,很实用。
二维码开发:
首先在github上下载ZBar SDK
地址https://github.com/bmorton/ZBarSDK
下载BlockAlertActionSheet,
新建一个test工程。在Main》storyboard上拖放一个button点击button开始扫描。
为button连接插座事件。
- (IBAction)btnClicked:(id)sender{
}
将ZBarSDK包含在项目工程当中。添加库:QuartzCore.framework ,CoreVideo.framework ,CoreMedia.framework,libiconv.dylib,CoreGraphics.framework。
将BlockAlertActionSheet包含在项目工程当中
在 WSQViewController.h中引入头文件。
#import "ZBarSDK.h"
#import "BlockAlertView.h"
遵循协议 ZBarReaderDelegate,
#pragma mark - ZBarReaderDelegate<UIImagePickerControllerDelegate>
- (void) readerControllerDidFailToRead: (ZBarReaderController*) reader
withRetry: (BOOL) retry
{
}
//二维码
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
}
定义实例变量:
ZBarReaderViewController *reader;
UIView* line; //二维码扫描线。
BOOL isBottom;
NSTimer* lineTimer;//二维码扫描线计时器。
自定义二维码扫描界面,(想法是这样的,先把reader原来的界面全部清空,然后自定义界面,因为ZBarSDK是分装好的静态库,)
-(void)setOverlayStyle:(ZBarReaderViewController *)reader_{
for (UIView *temp in [reader_.view subviews]){
for (UIButton* btn in [temp subviews]) {
if ([btn isKindOfClass:[UIButton class]]) {
[btn removeFromSuperview];
}
}
//去掉toolbar
for (UIToolbar* tool in [temp subviews]) {
if ([tool isKindOfClass:[UIToolbar class]]) {
[tool setHidden:YES];
[tool removeFromSuperview];
}
}
isBottom = NO;
//扫描线
line = [[UIView alloc] initWithFrame:CGRectMake(40, 105, 240, 2)];
line.backgroundColor = [UIColor greenColor];
[reader_.view addSubview:line];
lineTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(moveLine) userInfo:nil repeats:YES];
[lineTimer fire];
UIImage *scanningBg = [UIImage imageNamed:@"scanning-568h.png"];
CGSize size = [UIScreen mainScreen].bounds.size;
UIImageView *scanningView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
scanningView.image = scanningBg;
[reader_.view addSubview:scanningView];
//用于取消操作的button
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIImage *bimage = [UIImage imageNamed:@"yellowButton.png"];
//[cancelButton setBackgroundImage:bimage forState:UIControlStateDisabled];
[cancelButton setBackgroundColor:[UIColor whiteColor]];
[cancelButton setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[cancelButton setFrame:CGRectMake(20, size.height - 84, 280, 40)];
[cancelButton setTitle:@"取消" forState:UIControlStateNormal];
[cancelButton.titleLabel setFont:[UIFont boldSystemFontOfSize:20]];
[cancelButton addTarget:self action:@selector(dismissOverlayView:)forControlEvents:UIControlEventTouchUpInside];
[reader_.view addSubview:cancelButton];
}
}
//屏幕移动扫描线。
-(void)moveLine{
CGRect lineFrame = line.frame;
CGFloat y = lineFrame.origin.y;
if (!isBottom) {
isBottom = YES;
y=y+245.0;
lineFrame.origin.y = y;
[UIView animateWithDuration:1.5 animations:^{
line.frame = lineFrame;
}];
}else if(isBottom){
isBottom = NO;
y = y -245;
lineFrame.origin.y = y;
[UIView animateWithDuration:1.5 animations:^{
line.frame = lineFrame;
}];
}
}
// 点击cancel button事件
- (void)dismissOverlayView:(id)sender{
[lineTimer invalidate];
[reader dismissModalViewControllerAnimated:YES];
}
接下来在viewdidload中初始化 reader
- (void)viewDidLoad
{
[super viewDidLoad];
reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.wantsFullScreenLayout = NO;
//隐藏底部控制按钮
reader.showsZBarControls = NO;
[self setOverlayStyle:reader];//
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
}
在button事件中添加跳转到扫描界面的代码。
- (IBAction)btnClicked:(id)sender {
[self presentViewController:reader animated:YES completion:Nil];
}
定义内置留言器 WebViewVC.h,拖拽一个uiwebview连接插座变量 aWebView。将uiwebview的delegate设置为self
WebViewVC.h遵循协议 UIWebViewDelegate,
在 WebViewVC.h定义全局变量:@property (nonatomic,retain) NSString* urlStr;
在 WebViewVC.h的viewDidLoad加载网页。
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.urlStr && [self.urlStr rangeOfString:@"http:"].length>0) {
NSLog(@"%@",self.urlStr);
NSURL *url =[NSURL URLWithString:self.urlStr];
NSLog(@"open web with:%@",url);
NSURLRequest *request =[NSURLRequest requestWithURL:url];
_aWebView = [[UIWebView alloc]initWithFrame:self.view.frame];
_aWebView.delegate =self;
[self.view addSubview:_aWebView];
[_aWebView loadRequest:request];
}
}
最后再WSQViewController.h中处理扫描结果。
在- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info做扫描结果的判断:
#pragma mark - ZBarReaderDelegate<UIImagePickerControllerDelegate>
- (void) readerControllerDidFailToRead: (ZBarReaderController*) reader
withRetry: (BOOL) retry
{
BlockAlertView *bAlert = [BlockAlertView alertWithTitle:@"结果:" message:@"扫描失败,无法读取二维码信息"];
[bAlert addButtonWithTitle:@"知道了" block:nil];
[bAlert show];
}
//二维码
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
if(symbol.data && [symbol.data rangeOfString:@"http:"].length > 0)
{
NSString *regex = @"http+:[^\\s]*";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
//正则表达式判断是否包含 http:
if ([predicate evaluateWithObject:symbol.data])
{
//判断是不是我们自己的二维码
if ([symbol.data rangeOfString:@"http://itunes.apple.com/cn/app/id794862904"].length>0&& [[symbol.data componentsSeparatedByString:@"?"] count]>1) {
NSString* strUrl =symbol.data;
WebViewVC* web = [[WebViewVC alloc] initWithNibName:@"WebViewVC" bundle:nil];
web.urlStr = strUrl;
NSLog(@"strurl = %@",strUrl);
UINavigationController* navi = [[UINavigationController alloc] initWithRootViewController:web];
[reader presentViewController:navi animated:YES completion:nil];
}else{
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:symbol.data]];
}
}else{
//不是网页链接的情况。
NSString* msgBody = [symbol.data stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
BlockAlertView *bAlert = [BlockAlertView alertWithTitle:@"结果:" message:msgBody];
[bAlert addButtonWithTitle:@"知道了" block:nil];
[bAlert show];
}
}else if ([symbol.data rangeOfString:@"@@"].length > 0){
NSArray* array = [symbol.data componentsSeparatedByString:@"@@"];
NSLog(@"ARRAY = %@",array);
if (array && [array count]>0) {
NSString *msg = [NSString stringWithFormat:@"",[array description]];
BlockAlertView *bAlert = [BlockAlertView alertWithTitle:@"结果:" message:msg];
NSMutableString* strBody = [[NSMutableString alloc] initWithCapacity:3];
for (NSString* str in array) {
NSArray* tempArray = [str componentsSeparatedByString:@"["];
if (tempArray&& [tempArray count]>0) {
NSString* key = [tempArray objectAtIndex:0];
NSString* valueStr = [tempArray objectAtIndex:1];
NSString* value = [[valueStr componentsSeparatedByString:@"]"] objectAtIndex:0];
if ([key isEqualToString:@"url"]) {
[bAlert setCancelButtonWithTitle:@"打开网页" block:^{
//在这里打开网页
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString: value]];
[self openWebViewOf:value];
}];
}
else if([key isEqualToString:@"tel"]){
[bAlert setCancelButtonWithTitle:@"打电话" block:^{
//在这里打开网页
NSString* strTel = [NSString stringWithFormat:@"tel://%@",value];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:strTel]];
}];
}
}
}
[bAlert show];
}
}
//[reader dismissViewControllerAnimated:YES completion:nil];
}
注:
打开appstore下载app有两中方式。
第一种:
itms-apps://ax/itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReViews?type=Purpe+Software&id=794862904?mt=8"
第二种:
itms-apps://itunes.apple.com/cn/app/id794862904?url=http://xyk.cebbank.com,
为了骗过第三方的扫描软件,比如,微信,淘宝,那么必须在连接中加上 http:// 这样才行。
将第一种方式改成。
http://ax/itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReViews?type=Purpe+Software&id=794862904?mt=8"在微信中还是不跳。
那么就采用第二种方式。
http://itunes.apple.com/cn/app/id794862904?url=http://xyk.cebbank.com
这样的话就很容易的解决了微信扫一扫跳转的问题了,
最开始,我甚至使用的一个网页连接,然后在打开网页的时候让网页重定向,但是微信死活就是不跳转,但是我又发现携程网的app二维码也是这种方式,携程可以跳,让我纠结了半天。最后查看携程的跳转连接。发现它总共跳转了四次如下,
http://m.ctrip.com/m/c3,
http://m.ctrip.com/market/download.aspx?from=c3,
http://itunes.apple.com/cn/app/id379395415?mt=8,
itms-apps://itunes.apple.com/cn/app/id379395415?mt=8,
以我目前的情况是没时间搞它了,不知道有没有大牛给解答一下。
最后附上我写的html跳转页面。
<!DOCTYPE html">
<html>
<body>
<script type="text/javascript">
window.location = "mqq:open";
window.location="itms-apps://itunes.apple.com/cn/app/794862904?mt=8";
</script>
<lable>
是事实上是
</lable>
</body>
</html>
附上背景图:
ios二维码扫描插件,适配当前主流扫描软件,自定义扫描界面。的更多相关文章
- Ios二维码扫描(系统自带的二维码扫描)
Ios二维码扫描 这里给大家介绍的时如何使用系统自带的二维码扫描方法和一些简单的动画! 操作步骤: 1).首先你需要搭建UI界面如图:下图我用了俩个imageview和一个label 2).你需要在你 ...
- 二维码生成插件qrious及网站扫码登录的一些理解
什么是二维码 二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型. ...
- jquery二维码生成插件_二维码生成器
jquery二维码生成插件_二维码生成器 下载地址:jquery生成二维码.rar
- 基于jquery类库的绘制二维码的插件jquery.qrcode.js
jquery.qrcode.min.js 如下 (function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.d ...
- 二维码生成插件qrious
1.qrious是基于canvas的纯JS二维码生成插件 1.1什么是二维码 二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的B ...
- iOS二维码扫描IOS7系统实现
扫描相关类 二维码扫描需要获取摄像头并读取照片信息,因此我们需要导入系统的AVFoundation框架,创建视频会话.我们需要用到一下几个类: AVCaptureSession 会话对象.此类作为硬件 ...
- iOS - 二维码扫描和应用跳转
序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar.使用时集成麻烦, ...
- iOS二维码生成、识别、扫描等
二维码扫描 前言: 最近的项目中使用到了二维码,二维码这个模块功能也完成:觉得还是有必要总结一下用来做记录.好长时间没有写二维码了都忘记在差不多了,重新拾起来还是挻快的. 二维码使用场景: 生活中有很 ...
- iOS二维码扫描的实现(Swift)
随着二维码的普遍使用,二维码扫描也成为了很多app的一个基本功能,本篇主要来介绍一下如何实现一个简单的二维码扫描功能.本文使用了XCode自带的AVFoundation 库,利用Swfit语言实现. ...
随机推荐
- ReactNative 踩坑小计
使用ES6語法編寫Component時綁定事件需要用this.MethodName.bind(this),否則MethodName中無法使用this <TouchableHighlight on ...
- homework09-虐心的现程设终于要告一段落了
V3.0版本今天凌晨出炉 添加了随机生成 添加了文件打开 完全按照老师的要求搞定了 V2.0版本更新 添加了中间数组变量显示 这次作业写了整整一天,把以前能用的代码都改了一个遍 最后变成了网页版的小程 ...
- Spring入门(6)-使用注解装配
Spring入门(6)-使用注解装配 本文介绍如何使用注解装配. 0. 目录 使用Autowired 可选的自动装配 使用Qualifier选择 1. 使用Autowired package com. ...
- [iOS 多线程 & 网络 - 2.6] - 使用POST上传JSON数据 & 多值参数
A.上传JSON 1.思路: 必须使用POST方法才能上传大量JSON数据 设置请求头:设置Content-Type 设置请求体,JSON实际相当于字典,可以用NSDictionary NSJSONS ...
- VMware Workstation 11.0 官方中文版最强虚拟机软件(附下载地址)
VMware Workstation 11.0 新版本功能一览: 支持 Windows 8.1 Update.Windows Server 2012 R2.Ubuntu 14.10.RHEL 7.Ce ...
- Actions 动作集
--> 移动鼠标到指定位置(先触发onMouseOver动作) Actions action = new Actions(driver); WebElement th ...
- 【M1】仔细区别pointers和references
1.引用必须初始化,而且不能修改指向,这一点和const对象十分相似. 2.引用和指针用法不同,对于引用int& ri = a; rhs是个对象,引用前面加&:对于指针,int* pi ...
- delphi 保存网页
保存网页. htmluses ActiveX;procedure TForm1.Button1Click(Sender: TObject);var persist :IPersistfile;beg ...
- poj 1338 Ugly Numbers(丑数模拟)
转载请注明出处:viewmode=contents">http://blog.csdn.net/u012860063? viewmode=contents 题目链接:id=1338&q ...
- material-singleinputform
https://github.com/HeinrichReimer/material-singleinputform https://play.google.com/store/apps/detail ...