iOS 开发 二维码扫描详解
2016-12-07 22:20
906 查看
1.扫描二维码的控制器.m代码
#import "JDGScanQRcodeController.h" #import <AVFoundation/AVFoundation.h> #import <SafariServices/SafariServices.h> #import "JDGScanQRcodeView.h" @interface JDGScanQRcodeController ()<AVCaptureMetadataOutputObjectsDelegate> // 1.输入设备(采集信息) 摄像头 键盘 麦克风 @property (nonatomic, strong) AVCaptureDeviceInput *deviceInput; // 2.输出设备(解析数据) Metadata:元数据 @property (nonatomic, strong) AVCaptureMetadataOutput *metadataOutput; // 3.会话 (连接输入和输出设备) @property (nonatomic, strong) AVCaptureSession *session; // 4.预览的图层 @property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; @property (nonatomic, weak) JDGScanQRcodeView *scanQRcodeView; @end @implementation JDGScanQRcodeController - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"扫描二维码"; [self setUpUI]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // 控制器即将出先的时候开启会发,进行扫描 [self.session startRunning]; } - (void)setUpUI { // 二维码本质就是一个字符串 // 1.输入设备(采集信息) 摄像头 键盘 麦克风 // 默认就是后置摄像头 AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; self.deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil]; // 2.输出设备(解析数据) self.metadataOutput = [[AVCaptureMetadataOutput alloc] init]; // 设置代理 [self.metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; // 3.会话 (连接输入和输出设备) self.session = [[AVCaptureSession alloc] init]; if ([self.session canAddInput:self.deviceInput]) { [self.session addInput:self.deviceInput]; } if ([self.session canAddOutput:self.metadataOutput]) { [self.session addOutput:self.metadataOutput]; } // 设置解析的类型 不要写在会话之前 会崩溃 self.metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode]; // 预览图层的主要功能就是将摄像头采集的数据及时的传输到预览图层,使得用户可以在预览图层实时的看到画面,主要类是AVCapturePreviewLayer,创建起来也非常容易 //自定义扫描视图 JDGScanQRcodeView *scanQRcodeView = [[JDGScanQRcodeView alloc] initWithFrame:self.view.bounds]; self.scanQRcodeView = scanQRcodeView; scanQRcodeView.session = self.session; [self.view addSubview:scanQRcodeView]; // 5.开启会话 [self.session startRunning]; } // 实现AVCaptureMetadataOutputObjectsDelegate // 解析到二维码数据后调用 // metadataObjects:解析到的信息 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { // 关闭会话 [self.session stopRunning]; // 不能移除layer,移除后返回什么东西都没有了 // [self.scanQRcodeView removeFromSuperview]; for (AVMetadataMachineReadableCodeObject * objc in metadataObjects) { NSLog(@"%@",objc.stringValue); // 类似于Safari浏览器加载扫描出来的URLString进行加载页面 SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:objc.stringValue]]; [self presentViewController:safariVC animated:YES completion:nil]; } }
自定义预览图层
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface JDGScanQRcodeView : UIView // session @property (nonatomic, strong) AVCaptureSession *session; @end
#import "JDGScanQRcodeView.h" #import "Masonry.h" @interface JDGScanQRcodeView () // 图框 @property (nonatomic, strong) UIImageView *imageView; // 扫描线 @property (nonatomic, strong) UIImageView *lineImageView; // 定时器开启扫描线来回移动 @property (nonatomic, strong) NSTimer *timer; @end @implementation JDGScanQRcodeView - (void)setSession:(AVCaptureSession *)session { _session = session; // 预览图层 AVCaptureVideoPreviewLayer *layer = (AVCaptureVideoPreviewLayer *)self.layer; layer.session = session; } // 初始化预览图层 + (Class)layerClass { return [AVCaptureVideoPreviewLayer class]; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self initUiConfig]; } return self; } //在一个视图中设置二维码UI的垃圾代码 - (void)initUiConfig { //设置背景图片 self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"myCenter_pick_bg.png"]]; //设置位置到界面的中间 self.imageView.frame = CGRectMake(self.bounds.size.width * 0.5 - 140, self.bounds.size.height * 0.5 - 140, 280, 280); //添加到视图上 [self addSubview:self.imageView]; //初始化二维码的扫描线的位置 self.lineImageView = [[UIImageView alloc] initWithFrame:CGRectMake(30, 10, 220, 2)]; self.lineImageView.image = [UIImage imageNamed:@"myCenter_line.png"]; [self.imageView addSubview:self.lineImageView]; UILabel *tipLabel = [[UILabel alloc] init]; tipLabel.text = @"将二维码放入框内,即可自动扫描"; tipLabel.font = [UIFont systemFontOfSize:14.0]; tipLabel.textColor = [UIColor whiteColor]; [self addSubview:tipLabel]; [tipLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.imageView.mas_bottom).offset(10); make.centerX.mas_equalTo(self.mas_centerX); }]; //开启定时器 self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(animation) userInfo:nil repeats:YES]; } // 扫描线动态扫描 - (void)animation { [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ self.lineImageView.frame = CGRectMake(30, 260, 220, 2); } completion:^(BOOL finished) { self.lineImageView.frame = CGRectMake(30, 10, 220, 2); }]; } @end
实例
相关文章推荐
- iOS开发笔记(四)InApp Purchase always returning invalid code
- iOS开发:常见问题及解决方案(持续更新...)
- iOS 开发阅读笔记
- iOS开发笔记 1、iOS版本和Objective-C
- iOS开发笔记 5、开发工具Xcode,Inteface Builder
- iOS开发笔记 2、Cocoa简明
- ios 开发搜集到的有用参考信息汇总
- 我常用的几个提高iOS开发效率的开源类库及工具
- ios开发基础知识 - 1
- iOS开发:我的开源项目(不定期更新...)
- iOS开发笔记(七) A provisioning profile named embedded.mobileprovision already exists on this computer
- 国内平台游戏借苹果iOS爆发:游戏开发产值过亿
- MonoDevelop/MonoTouch SDK开发iOS程序体验!
- iOS开发笔记(八)How to test an iPhone application update?
- iOS开发笔记(一)
- 上海奇异岛工作室高薪诚聘iOS软件开发人员
- iOS开发笔记(六)网络编程总结
- 虚幻开发套件将于本周内开始支持iOS
- iOS开发笔记 4、iOS中的Cocoa、设计模式等
- iOS开发笔记 6、View Controllers【MVC】