title: iOS二维码操做
date: 2016-05-11 16:51:31ios
功能:扫描二维码、条形码,生成二维码。具体使用请看项目。github地址 喜欢的朋友们给个星星吧。萌萌哒。git
添加二维码界面github
假如你须要在项目中须要使用生成二维码的功能,仅仅须要引入头文件和建立二维码视图并添加就能够了。例如这样:session
#import "XYLScaningCode.h" @interface ViewController () @property(strong, nonatomic)XYLBinaryCodeView *binaryCodeView; //二维码界面 @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor]; //设置生成二维码界面 self.binaryCodeView = [[XYLBinaryCodeView alloc]initWithFrame:[UIScreen mainScreen].bounds]; //设置二维码的内容 self.binaryCodeView.inputData = @"www.baidu.com"; [self.view insertSubview:self.binaryCodeView atIndex:1]; }
添加扫描二维码、条形码功能框架
假如你须要使用扫码的功能,那代码稍微多一点点,多的部分就是开始扫码、读取扫码结果、处理扫码结果那部分。ide
一样的,你也须要引入上面的头文件;atom
而后就是一些逻辑了,不用太担忧,由于我会有不少的注释,并且后面还会详细分析。代码以下:spa
#import "ViewController.h" #import "XYLScaningCode.h" @interface ViewController ()<UIAlertViewDelegate, AVCaptureMetadataOutputObjectsDelegate, XYLScanViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> { AVCaptureDevice *frontCamera; //前置摄像机 AVCaptureDevice *backCamera; //后置摄像机 AVCaptureSession *session; //捕捉对象 AVCaptureVideoPreviewLayer *previewLayer; AVCaptureInput *input; //输入流 AVCaptureMetadataOutput *output;//输出流 BOOL isTorchOn; } @property (nonatomic, assign) XYLScaningWarningTone tone; @property (nonatomic, strong) XYLScanView *overView; //扫码界面 @property(strong, nonatomic)XYLBinaryCodeView *binaryCodeView; //二维码界面 @property(weak, nonatomic)XYLToolButton *scanButton; @property(weak, nonatomic)XYLToolButton *payCodeButton; @property(weak, nonatomic)UILabel *titleLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor]; [self scanSelected]; } //点击扫码 -(void)scanSelected { if (![self.overView isDisplayedInScreen]) { #if TARGET_IPHONE_SIMULATOR UIAlertController *simulatorAlert = [UIAlertController alertControllerWithTitle:nil message:@"虚拟机不支持相机" preferredStyle:UIAlertControllerStyleActionSheet]; [simulatorAlert addAction:[UIAlertAction actionWithTitle:@"好吧" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { return; }]]; [self presentViewController:simulatorAlert animated:YES completion:nil]; #elif TARGET_OS_IPHONE //判断相机权限 [self isVideoUseable]; self.binaryCodeView.hidden = YES; if (self.overView) { self.overView.hidden = NO; }else{ //添加扫面界面视图 [self initOverView]; [self initCapture]; [self config]; [self initUI]; [self addGesture]; } #endif } } -(void)isVideoUseable { AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) { UIAlertController *simulatorAlert = [UIAlertController alertControllerWithTitle:nil message:@"相机权限未开通,请打开" preferredStyle:UIAlertControllerStyleActionSheet]; [simulatorAlert addAction:[UIAlertAction actionWithTitle:@"好吧" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { return; }]]; [self presentViewController:simulatorAlert animated:YES completion:nil]; } }
/** * 添加扫码视图 */ - (void)initOverView { if (!_overView) { _overView = [[XYLScanView alloc]initWithFrame:[UIScreen mainScreen].bounds lineMode:XYLScaningLineModeDeafult ineMoveMode:XYLScaningLineMoveModeUpAndDown]; _overView.delegate = self; [self.view insertSubview:_overView atIndex:1]; } } //设置扫描反馈模式:这里是声音提示 - (void)config{ _tone = XYLScaningWarningToneSound; }
- (void)initCapture { //建立捕捉会话 session = [[AVCaptureSession alloc]init]; //高质量采集率 [session setSessionPreset:AVCaptureSessionPresetHigh]; //获取摄像设备 NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; for (AVCaptureDevice *camera in devices) { if (camera.position == AVCaptureDevicePositionFront) { frontCamera = camera; }else{ backCamera = camera; } } //建立输入流 input = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:nil]; //输出流 output = [[AVCaptureMetadataOutput alloc]init]; //设置代理 在主线程里刷新 [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //添加输入设备(数据从摄像头输入) if ([session canAddInput:input]) { [session addInput:input]; } //添加输出数据 if ([session canAddOutput:output]) { [session addOutput:output]; } //设置设置输入元数据的类型(以下设置条形码和二维码兼容) output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode]; //添加扫描图层 previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session]; previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; previewLayer.frame = self.view.layer.bounds; [self.view.layer insertSublayer:previewLayer atIndex:0]; //开始捕获 [session startRunning]; CGFloat screenHeight = ScreenSize.height; CGFloat screenWidth = ScreenSize.width; CGRect cropRect = CGRectMake((screenWidth - TransparentArea([_overView width], [_overView height]).width) / 2, (screenHeight - TransparentArea([_overView width], [_overView height]).height) / 2, TransparentArea([_overView width], [_overView height]).width, TransparentArea([_overView width], [_overView height]).height); //设置扫描区域 [output setRectOfInterest:CGRectMake(cropRect.origin.y / screenHeight, cropRect.origin.x / screenWidth, cropRect.size.height / screenHeight, cropRect.size.width / screenWidth)]; }
/** * 获取扫描数据 */ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { NSString *stringValue; if (metadataObjects.count > 0) { AVMetadataMachineReadableCodeObject *metadateObject = [metadataObjects objectAtIndex:0]; stringValue = metadateObject.stringValue; [self readingFinshedWithMessage:stringValue]; [previewLayer removeFromSuperlayer]; } } /** * 读取扫描结果 */ - (void)readingFinshedWithMessage:(NSString *)msg { if (msg) { [session stopRunning]; [self playSystemSoundWithStyle:_tone]; [self.overView stopMove]; UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:msg preferredStyle:UIAlertControllerStyleActionSheet]; [alert addAction:[UIAlertAction actionWithTitle:@"肯定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { NSLog(@"扫描出来结果%@",msg); //todo:在这里添加扫描结果后的处理 [self.overView removeFromSuperview]; self.overView = nil; [self payCodeSelected]; }]]; [self presentViewController:alert animated:YES completion:nil]; }else { UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"读取失败" preferredStyle:UIAlertControllerStyleActionSheet]; [alert addAction:[UIAlertAction actionWithTitle:@"肯定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { NSLog(@"点击了肯定"); }]]; [self presentViewController:alert animated:true completion:nil]; } }
/** * 展现声音提示 */ - (void)playSystemSoundWithStyle:(XYLScaningWarningTone)tone{ NSString *path = [NSString stringWithFormat:@"%@/scan.wav", [[NSBundle mainBundle] resourcePath]]; SystemSoundID soundID; NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)(filePath), &soundID); switch (tone) { case XYLScaningWarningToneSound: AudioServicesPlaySystemSound(soundID); break; case XYLScaningWarningToneVibrate: AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); break; case XYLScaningWarningToneSoundAndVibrate: AudioServicesPlaySystemSound(soundID); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); break; default: break; } }
说明线程
你可能看到了,添加扫码功能的时候,要遵循更多的协议,这是由于这里使用了AVFoundation框架Apple原生扫描二维码的一些功能,只须要遵循这些协议就能够调用里面的功能了。例如这里的获取扫码结果的方法代理
/** * 获取扫描数据 */ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection;
而其他的,这里详细的注释就能够帮助你理解这些代码了,若是想深刻了解具体实现过程,建议能够看一下源码github地址。