iOS 条形码、二维码心得
来源:互联网 发布:蚁群优化算法 matlab 编辑:程序博客网 时间:2024/06/10 15:45
写这篇文章之前,先说一声抱歉,因为邮箱开发那篇文章已经三个星期没有更新了。因为邮箱开发篇幅较长,并且公司现在工作很多,来不及更新,预计会在五月中旬到六月更新完吧。
简单介绍一下JSScanViewController的几点优势(其实JS就是技术的首字母啦,哈哈。。。)。
- JSCodeScan能够识别二位码和条形码
- 界面简单,优雅,清晰
- 加入了闪光灯功能,扫码不受环境限制
- 嵌入非常简单,只需两行代码JSScanViewController *sv = [[JSScanViewController alloc] init];
[self.navigationController pushViewController:sv animated:YES]; - 扫描结果通过代理回调,结果随便怎么用,随便哪里用
- JSCodeScan对你的应用做到零侵入,随心所欲,想嵌就嵌,想删就删,丝毫不影响你的应用
首先,我在.h文件声明了两个可选的代理方法,一个是用户点击返回上一级的操作时,会触发–scanViewControllerWillBack:这个方法。另一个是扫描成功时会触发–scanViewController:result:这个方法,供开发者调用。这两个方法就不用说明了吧。
@protocol JSScanViewControllerDelegate <NSObject>@optional/** 扫描成功回调 @param scanVc 扫描控制器本身 @param result 扫描的结果 */-(void)scanViewController:(JSScanViewController *)scanVc result:(NSString *)result;/** 点击返回按钮回调 @param scanVc 扫描控制器本身 */-(void)scanViewControllerWillBack:(JSScanViewController *)scanVc;
.m文件的实现如下
#import "JSScanViewController.h"#import <AVFoundation/AVFoundation.h>#import "ScanAreaView.h"#import "UIView+Extension.h"#define iWidth [UIScreen mainScreen].bounds.size.width#define iHeight [UIScreen mainScreen].bounds.size.height#define margin 3.0#define bottomHeight 100.0typedef enum{ codeType_QRCode, //二维码 codeType_BarCode, //条形码}codeType;@interface JSScanViewController ()<AVCaptureMetadataOutputObjectsDelegate, UIAlertViewDelegate>@property(nonatomic, strong) AVCaptureDevice *device;@property(nonatomic, strong) AVCaptureMetadataOutput *output;@property(nonatomic, strong) AVCaptureSession *session; //输入输出的中间桥梁@property(nonatomic, assign) codeType type; //扫描类型@property (strong, nonatomic) UISegmentedControl *segment;@property(nonatomic, strong) ScanAreaView *scanView; //扫描框@property(nonatomic, assign) CGFloat scanLineY; //扫描线的Y值@property(nonatomic, strong) UIImageView *scanLine; //扫描线@property(nonatomic, strong) UIImageView *maskLayer; //遮罩层@property(nonatomic, strong) UIButton *lightBtn; //闪光灯按钮@end@implementation JSScanViewController-(UISegmentedControl *)segment{ if (_segment == nil) { _segment = [[UISegmentedControl alloc] initWithFrame:CGRectMake(30, iHeight-70, iWidth-60, 41)]; [_segment insertSegmentWithTitle:@"条形码" atIndex:0 animated:YES]; [_segment insertSegmentWithTitle:@"二维码" atIndex:1 animated:YES]; [_segment addTarget:self action:@selector(switchType:) forControlEvents:UIControlEventValueChanged]; } return _segment;}/** * 切换扫码类型 * * @param sender 切换控件 */- (void)switchType:(UISegmentedControl *)sender { if (sender.selectedSegmentIndex == 0) { //条形码 [self barCodeSetting]; }else if (sender.selectedSegmentIndex == 1) { //二维码 [self QRCodeSetting]; } [self.scanView setNeedsDisplay];}- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; UIButton *backBtn = [[UIButton alloc] initWithFrame:CGRectMake(20.0, 20.0, 44.0, 44.0)]; [backBtn setImage:[UIImage imageNamed:@"icon-barcode-back"] forState:UIControlStateNormal]; [backBtn addTarget:self action:@selector(backBtnClick) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:backBtn]; UIButton *lightBtn = [[UIButton alloc] initWithFrame:CGRectMake(iWidth-64.0, 20.0, 44.0, 44.0)]; [lightBtn setImage:[UIImage imageNamed:@"icon-flash-off"] forState:UIControlStateNormal]; [lightBtn setImage:[UIImage imageNamed:@"icon-flash-on"] forState:UIControlStateSelected]; [lightBtn addTarget:self action:@selector(lightBtnClick:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:lightBtn]; _lightBtn = lightBtn; [self.view addSubview:self.segment]; [self.view addSubview:self.maskLayer]; [self.view addSubview:self.scanView]; [self.scanView addSubview:self.scanLine]; self.scanLine.frame = CGRectMake(margin, 0, _scanView.frame.size.width-(2*margin), 1.0); //获取摄像设备 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; _device = device; //创建输入流 AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; //创建输出流 AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init]; _output = output; // output.rectOfInterest = CGRectMake(0, 0, 1, 1); //设置代理 在主线程里刷新 [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //初始化链接对象 _session = [[AVCaptureSession alloc] init]; //高质量采集率 [_session setSessionPreset:AVCaptureSessionPresetHigh]; [_session addInput:input]; [_session addOutput:output]; AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:_session]; layer.videoGravity=AVLayerVideoGravityResizeAspectFill; layer.frame=CGRectMake(0, 0, iWidth, iHeight-bottomHeight); [self.view.layer insertSublayer:layer atIndex:0]; [self barCodeSetting]; //开始捕获 [_session startRunning]; CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink)]; [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];}/** * 返回按钮的点击 */-(void)backBtnClick{ NSLog(@"scanViewControllerWillBack"); if (self.delegate && [self.delegate respondsToSelector:@selector(scanViewControllerWillBack:)]) { [self.delegate scanViewControllerWillBack:self]; }}/** * 闪关灯按钮的点击 * * @param btn 闪关灯按钮 */-(void)lightBtnClick:(UIButton *)btn{ btn.selected = !btn.selected; if ([_device hasTorch] && [_device hasFlash]){ [_device lockForConfiguration:nil]; if (btn.selected) { [_device setTorchMode:AVCaptureTorchModeOn]; [_device setFlashMode:AVCaptureFlashModeOn]; } else { [_device setTorchMode:AVCaptureTorchModeOff]; [_device setFlashMode:AVCaptureFlashModeOff]; } [_device unlockForConfiguration]; } NSLog(@"lightBtnClick");}-(UIImageView *)maskLayer{ if (_maskLayer == nil) { _maskLayer = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, iWidth, iHeight-bottomHeight)]; _maskLayer.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4]; } return _maskLayer;}/** * 控制扫描线的位置 */-(void)handleDisplayLink{ self.scanLineY += 1; if (self.scanLineY> self.scanView.frame.size.height) { self.scanLineY = 0.0; } self.scanLine.y = self.scanLineY;}/** * 扫描结果 */-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ if (metadataObjects.count>0) { [_session stopRunning]; _lightBtn.selected = NO; AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0]; NSString *result = metadataObject.stringValue; if (self.delegate && [self.delegate respondsToSelector:@selector(scanViewController:result:)]) { [self.delegate scanViewController:self result:result]; } //输出扫描字符串 NSLog(@"扫描结果:%@",result); NSLog(@"%@", NSStringFromCGRect(_output.rectOfInterest)); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"扫描结果" message:result delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil]; [alert show]; }}- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex == 0) { [_session startRunning]; }}/** * 条形码设置 */-(void)barCodeSetting{ self.type = codeType_BarCode; self.segment.selectedSegmentIndex = 0; //设置扫码支持的编码格式(条形码) _output.metadataObjectTypes=@[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]; _scanView.frame = [self scanAreaViewFrame];}/** * 二维码设置 */-(void)QRCodeSetting{ self.type = codeType_QRCode; self.segment.selectedSegmentIndex = 1; //设置扫码支持的编码格式(二维码) _output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode]; _scanView.frame = [self scanAreaViewFrame];}-(UIImageView *)scanLine{ if (_scanLine == nil) { _scanLine = [[UIImageView alloc] init]; _scanLine.backgroundColor = [UIColor yellowColor]; } return _scanLine;}-(ScanAreaView *)scanView{ if (_scanView == nil) { _scanView = [[ScanAreaView alloc] init]; _scanView.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.15]; _scanView.frame = [self scanAreaViewFrame]; } return _scanView;}/** * 设置扫码区域的大小 * * @return frame */-(CGRect)scanAreaViewFrame{ CGFloat AVCaptureVideoPreviewLayerHeight = iHeight-bottomHeight; if (self.type == codeType_BarCode) { CGFloat w = iWidth* 0.8; CGFloat h = w * 0.3; CGFloat x = (iWidth-w)*0.5; CGFloat y = iHeight / 4.0; self.scanLine.width = w-6.0; CGFloat outputX = x / iWidth; CGFloat outputY = y / AVCaptureVideoPreviewLayerHeight; CGFloat outputW = w / iWidth; CGFloat outputH = h / AVCaptureVideoPreviewLayerHeight; //经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。 _output.rectOfInterest = CGRectMake(outputY, outputX, outputH, outputW); return CGRectMake(x, y, w, h); }else { CGFloat w = iWidth* 0.65; CGFloat h = w; CGFloat x = (iWidth-w)*0.5; CGFloat y = iHeight / 4.0; self.scanLine.width = w-6.0; CGFloat outputX = x / iWidth; CGFloat outputY = y / AVCaptureVideoPreviewLayerHeight; CGFloat outputW = w / iWidth; CGFloat outputH = h / AVCaptureVideoPreviewLayerHeight; //经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。 _output.rectOfInterest = CGRectMake(outputY, outputX, outputH, outputW); return CGRectMake(x, y, w, h); }}@end
感觉没有什么好说明的,代码里该注释的我已经注释了。
我还是说一下吧,万一真的有人不懂(其实没有必要解释的)。
#import "UIView+Extension.h"
这个类其实就是UI尺寸的一些拓展,比如x,y,width,height,size,center等等的一些东西。
#import "ScanAreaView.h"
ScanAreaView就是draw的扫描界面,具体实现也给你们吧。
@interface ScanAreaView()@property(nonatomic, strong) UIBezierPath *path1;@property(nonatomic, strong) UIBezierPath *path2;@property(nonatomic, strong) UIBezierPath *path3;@property(nonatomic, strong) UIBezierPath *path4;@end@implementation ScanAreaView- (void)drawRect:(CGRect)rect { CGFloat lineWidth = 15.0; CGFloat width = rect.size.width; CGFloat height = rect.size.height; //左上角 [self.path1 removeAllPoints]; [self.path1 moveToPoint:CGPointMake(0, lineWidth)]; [self.path1 addLineToPoint:CGPointMake(0, 0)]; [self.path1 addLineToPoint:CGPointMake(lineWidth, 0)]; self.path1.lineWidth = 5.0; [[UIColor greenColor] set]; [self.path1 stroke]; //右上角 [self.path2 removeAllPoints]; [self.path2 moveToPoint:CGPointMake(width-lineWidth, 0)]; [self.path2 addLineToPoint:CGPointMake(width, 0)]; [self.path2 addLineToPoint:CGPointMake(width, lineWidth)]; self.path2.lineWidth = 5.0; [[UIColor greenColor] set]; [self.path2 stroke]; //右下角 [self.path3 removeAllPoints]; [self.path3 moveToPoint:CGPointMake(width, height-lineWidth)]; [self.path3 addLineToPoint:CGPointMake(width, height)]; [self.path3 addLineToPoint:CGPointMake(width-lineWidth, height)]; self.path3.lineWidth = 5.0; [[UIColor greenColor] set]; [self.path3 stroke]; //左下角 [self.path4 removeAllPoints]; [self.path4 moveToPoint:CGPointMake(0, height-lineWidth)]; [self.path4 addLineToPoint:CGPointMake(0, height)]; [self.path4 addLineToPoint:CGPointMake(lineWidth, height)]; self.path4.lineWidth = 5.0; [[UIColor greenColor] set]; [self.path4 stroke];}-(UIBezierPath *)path1{ if (_path1==nil) { _path1 = [UIBezierPath bezierPath]; } return _path1;}-(UIBezierPath *)path2{ if (_path2==nil) { _path2 = [UIBezierPath bezierPath]; } return _path2;}-(UIBezierPath *)path3{ if (_path3==nil) { _path3 = [UIBezierPath bezierPath]; } return _path3;}-(UIBezierPath *)path4{ if (_path4==nil) { _path4 = [UIBezierPath bezierPath]; } return _path4;}@end
就这样了。挺简单的,这方面的资料网上一搜数不胜数。
没图没真相,好吧,我附上效果图。。。。
0 0
- iOS 条形码、二维码心得
- iOS 二维码,条形码扫描
- IOS扫描二维码条形码
- ios 二维码、条形码扫描
- iOS 二维码demo,条形码demo
- ios ZXing 二维码、条形码扫描
- iOS 生成二维码和条形码
- iOS原生二维码/条形码相关
- iOS-扫描二维码and条形码
- 在iOS上实现二维码功能、二维码、条形码、swift 二维码
- iOS 使用ZBarSDK扫描条形码和二维码
- iOS 使用ZBarSDK扫描条形码和二维码
- ios-使用ZBar来扫描二维码/条形码
- IOS 使用AVFoundation 扫描条形码、二维码等
- iOS 使用ZBarSDK扫描条形码和二维码
- iOS 使用ZBarSDK扫描条形码和二维码
- ios 使用ZBar读取条形码和二维码
- iOS系统原生二维码条形码扫描
- sql编程基础总结
- Sorting It All Out POJ
- json选择
- C语言中 scanf gets getchar 的区别
- JS 上传文件之FormData 与Blob 对象
- iOS 条形码、二维码心得
- 基于javamail简单实现邮件发送
- Retrofit 2.0 + OkHttp 3.0 配置
- numpy下的flatten()函数用法
- 链式堆栈
- 欢迎使用CSDN-markdown编辑器
- Mac使用SSH key连接vps
- Java中instanceof的用法
- HDU1518-Square