iOS 学习日志 : iOS原生二维码的扫描以及限定扫描范围
来源:互联网 发布:要怎么加盟农村淘宝 编辑:程序博客网 时间:2024/06/03 20:26
现在的app多少都会加入二维码扫描功能,方便快捷,开发中常常会碰到这样的需求.
定义会话和输出流对象
@property (nonatomic) AVCaptureSession *captureSession;@property (nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;
// 获取 AVCaptureDevice 实例 NSError * error; AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; // 初始化输入流 AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error]; if (!input) { NSLog(@"%@", [error localizedDescription]); return NO; } // 创建会话 _captureSession = [[AVCaptureSession alloc] init]; // 添加输入流 [_captureSession addInput:input]; // 初始化输出流 AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init]; // 添加输出流 [_captureSession addOutput:captureMetadataOutput]; // 创建dispatch queue. dispatch_queue_t dispatchQueue; dispatchQueue = dispatch_queue_create(kScanQRCodeQueueName, NULL); [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; // 设置数据类型 AVMetadataObjectTypeQRCode [captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]]; // 创建输出对象 _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession]; [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; [_videoPreviewLayer setFrame:self.view.bounds]; [self.view.layer addSublayer:_videoPreviewLayer]; // 开始会话 [_captureSession startRunning];
这里准备工作就做完了,在startRunning后就会开启二维码的扫描,然后遵守AVCaptureMetadataOutputObjectsDelegate
代理 ,在代理方法中处理扫码获得的数据
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ if (metadataObjects != nil && [metadataObjects count] > 0) { AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0]; NSString *result; [_captureSession stopRunning]; if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { result = metadataObj.stringValue; } else { NSLog(@"不是二维码"); } }}
这样最基础的二维码扫描就做完了,但是用户体验并不好,因为默认的是全屏扫描,而且原生的二维码扫描很快,容易误操作,影响用户体验.
所以我们需要限定扫描的范围,AVCaptureMetadataOutput 有对应的属性设置扫描范围,但是它的坐标系有些特殊 并不是常见的(x,y,width,height)而是(y,x,height,width),所以就需要将坐标翻转过来,下面是一个左右间距各50,居中的正方形扫描框,那么就将扫描范围限定在这个扫描框里。 AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[captureMetadataOutput setRectOfInterest:CGRectMake(([UIScreen mainScreen].bounds.size.height/2-([UIScreen mainScreen].bounds.size.width-100)/2)/
[UIScreen mainScreen].bounds.size.height,50/[UIScreen mainScreen].bounds.size.width, ([UIScreen mainScreen].bounds.size.width-100)/[UIScreen mainScreen].bounds.size.height, ([UIScreen mainScreen].bounds.size.width-100)/[UIScreen mainScreen].bounds.size.width)];
最后嘛 可以利用view的动画来完成扫描框的线性”扫描”,提升用户体验
下面是利用masory约束的一个 左右间距50并居中的扫描框,然后利用动画完成线性的扫描,欺骗用户…….0.0
UIView * anniView= [[UIView alloc]init]; anniView.tag = 111; [self.view addSubview:anniView]; [anniView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.view.mas_centerX); make.centerY.equalTo(self.view.mas_centerY); make.left.equalTo(self.view).with.offset(50); make.right.equalTo(self.view).with.offset(-50); make.width.equalTo(anniView.mas_height); }]; //扫描框 UIImageView * imageView = [[UIImageView alloc]init]; [anniView addSubview:imageView]; [imageView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(anniView).insets(UIEdgeInsetsMake(0, 0, 0, 0)); }]; imageView.image = [UIImage imageNamed:@"cornround"]; //扫描线 UIImageView * line = [[UIImageView alloc]init]; [anniView insertSubview:line aboveSubview:imageView]; line.backgroundColor = [UIColor clearColor]; line.image = [UIImage imageNamed:@"line"]; [line mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(anniView).with.offset(0); make.right.equalTo(anniView).with.offset(0); make.top.equalTo(anniView).with.offset(0); make.height.equalTo(@2); }]; CABasicAnimation *animationMove = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"]; [animationMove setFromValue:@(0)]; [animationMove setToValue:@([UIScreen mainScreen].bounds.size.width-102)]; animationMove.duration = 5.0f; animationMove.delegate = self; animationMove.repeatCount = OPEN_MAX; animationMove.removedOnCompletion = NO; animationMove.fillMode = kCAFillModeForwards; animationMove.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [line.layer addAnimation:animationMove forKey:animationKey];
最后在扫码获取到数据之后,停止扫描.并根据tag值获取UIImageView 移除动画,并把扫描框从当前视图中移除
- iOS 学习日志 : iOS原生二维码的扫描以及限定扫描范围
- iOS原生二维码生成与扫描以及条形码的扫描
- iOS原生二维码扫描
- iOS 原生二维码扫描
- iOS:原生二维码扫描
- iOS原生二维码扫描
- iOS原生扫描二维码
- ios原生二维码扫描
- iOS:原生二维码扫描
- ios原生二维码扫描
- iOS 原生二维码扫描
- iOS 原生二维码扫描
- iOS 原生扫描二维码
- iOS原生二维码扫描
- ios 原生二维码扫描以及需要注意事项
- 限定二维码扫描范围
- IOS 原生二维码扫描 学习笔记
- ios 原生二维码的扫描和生成
- 文字识别转换
- 从 SVN 迁移至 Gitlab + Gitflow 总结
- history显示时间、IP、用户
- Gartner 如何看 RASP 和 WAF?
- 11.使用NSUserDefaults存储存储
- iOS 学习日志 : iOS原生二维码的扫描以及限定扫描范围
- [ASP.NET教程] C#中如何实现数据拖动?(拖动图片,到TextBox,并显示)
- Learning Ceph
- Unity游戏开发使用Assetbundle加载场景实战
- 编辑文章 - 博客频道 - CSDN.NET
- Ext.js表单—Vbox布局(46)
- 代码签名探析
- svn分支开发与主干合并(branch & merge)
- JDBC编程详解