• iOS


    1、QRCode

    • 在 iOS7 以前,在 iOS 中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar 与 ZXing。iOS7 之后可以利用系统原生 API 生成二维码, iOS8 之后可以生成条形码, 系统默认生成的颜色是黑色。

      • 1、ZBar 在扫描的灵敏度上,和内存的使用上相对于 ZXing 上都是较优的,但是对于 “圆角二维码” 的扫描确很困难。
      • 2、ZXing 是 Google Code 上的一个开源的条形码扫描库,是用 java 设计的,连 Google Glass 都在使用的。但有人为了追求更高效率以及可移植性,出现了 c++ port。Github 上的 Objectivc-C port,其实就是用 OC 代码封装了一下而已,而且已经停止维护。这样效率非常低,在 instrument 下面可以看到 CPU 和内存疯涨,在内存小的机器上很容易崩溃。
      • 3、AVFoundation 无论在扫描灵敏度和性能上来说都是最优的,所以毫无疑问我们应该切换到 AVFoundation,需要兼容 iOS 6 或之前的版本可以用 ZBar 或 ZXing 代替。
    • 在 iOS8 + 系统中使用相机需要在 Info.plist 中添加 Privacy - Camera Usage Description,并设置其值。使用相册需要在 Info.plist 中添加 Privacy - Photo Library Usage Description,并设置其值。

      QRCode24

    • 按照下图在 Info.plist 文件中将 Localization native development region 的值改为 China。如果不设置此项弹出的相册页面中显示的按钮等为英文菜单。

      QRCode25

    2、系统原生二维码

    2.1 扫描二维码

    • 官方提供的接口非常简单,直接看代码,主要使用的是 AVFoundation。

      	// 包含头文件
      	#import <AVFoundation/AVFoundation.h>
      	
      	// 遵守协议
      	<AVCaptureMetadataOutputObjectsDelegate>
      	
      	// 输入输出的中间桥梁
      	@property (nonatomic, strong) AVCaptureSession *session;
      
      	// 扫描窗口
      	@property (nonatomic, strong) UIImageView *scanView;
      
      	// 创建扫描视图窗口,自定义方法
      	- (void)createdScanView {
      	    
      	    CGFloat margin = 50;
      	    CGRect scanFrame = CGRectMake(margin,
      	                                  margin + 20,
      	                                  self.view.bounds.size.width - margin * 2,
      	                                  self.view.bounds.size.width - margin * 2);
      	    
      	    self.scanView = [[UIImageView alloc] initWithFrame:scanFrame];
      	    
      	    self.scanView.image = [UIImage imageNamed:@"scan_bg2"];
      	    
      	    [self.view addSubview:self.scanView];
      	    
      	    // 创建扫描
      	    [self startScan];
      	}
      	
      	// 创建扫描,自定义方法
      	- (void)startScan {
      	    
      	    // 获取摄像设备
      	    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
      	    
      	    // 创建输入流
      	    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
      	
      	    // 创建输出流
      	    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
      	    
      	    // 设置代理,在主线程里刷新
      	    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
      	    
      	    // 设置有效扫描区域
      	    output.rectOfInterest = [self getScanCropWithScanViewFrame:self.scanView.frame readerViewBounds:self.view.bounds];
      	    
      	    // 初始化链接对象
      	    self.session = [[AVCaptureSession alloc] init];
      	    
      	    // 设置采集率,高质量
      	    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
      	    
      	    [self.session addInput:input];
      	    [self.session addOutput:output];
      	    
      	    // 设置扫码支持的编码格式(如下设置条形码和二维码兼容)
      	    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
      	                                   AVMetadataObjectTypeEAN13Code,
      	                                   AVMetadataObjectTypeEAN8Code,
      	                                   AVMetadataObjectTypeCode128Code];
      	    
      	    AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
      	    layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
      	    layer.frame = self.view.layer.bounds;
      	    [self.view.layer insertSublayer:layer atIndex:0];
      	    
      	    // 开始捕获
      	    [self.session startRunning];
      	}
      	
      	// 设置扫描区域的比例关系,自定义方法
      	- (CGRect)getScanCropWithScanViewFrame:(CGRect)scanViewFrame readerViewBounds:(CGRect)readerViewBounds {
      	    
      	    CGFloat x, y, width, height;
      	    
      	    x = scanViewFrame.origin.y / readerViewBounds.size.height;
      	    y = scanViewFrame.origin.x / readerViewBounds.size.width;
      	    width = scanViewFrame.size.height / readerViewBounds.size.height;
      	    height = scanViewFrame.size.width / readerViewBounds.size.width;
      	    
      	    return CGRectMake(x, y, width, height);
      	}
      	
      	// 获取扫描结果,AVCaptureMetadataOutputObjectsDelegate 协议方法
      	- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
      	                                                                 fromConnection:(AVCaptureConnection *)connection {
      	    
      	    if (metadataObjects.count > 0) {
      	        
      	        // 停止扫描
      	        [self.session stopRunning];
      	        
      	        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0];
      	        
      	        // 获取扫描结果
      	        NSString *resultString = metadataObject.stringValue;
      			        
      	        // 输出扫描字符串
      	        [[[UIAlertView alloc] initWithTitle:@"扫描成功"
      	                                    message:resultString
      	                                   delegate:nil
      	                          cancelButtonTitle:@"确定"
      	                          otherButtonTitles:nil] show];
      	    }
      	}
      
    • 一些初始化的代码加上实现代理方法便完成了二维码扫描的工作,这里我们需要注意的是,在二维码扫描的时候,我们一般都会在屏幕中间放一个方框,用来显示二维码扫描的大小区间,这里我们在AVCaptureMetadataOutput 类中有一个 rectOfInterest 属性,它的作用就是设置扫描范围。这个 CGRect 参数和普通的 Rect 范围不太一样,它的四个值的范围都是 0-1,表示比例。rectOfInterest 都是按照横屏来计算的,所以当竖屏的情况下 x 轴和 y 轴要交换一下,宽度和高度设置的情况也是类似。

    • 效果

      QRCode10 QRCode11

    2.2 读取二维码

    • 读取主要用到 CoreImage 不过要强调的是读取二维码的功能只有在 iOS8 之后才支持,我们需要在相册中调用一个二维码,将其读取,代码如下

      	// 遵守协议
      	<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
      
      	// 打开相册,选取图片,自定义方法
      	- (void)readQRCode {
      	    
      	    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
      	        
      	        // 初始化相册拾取器
      	        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
      	        
      	        // 设置资源
      	        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
      	        
      	        // 设置代理
      	        picker.delegate = self;
      	        
      	        [self presentViewController:picker animated:YES completion:nil];
      	        
      	    } else {
      	        
      	        NSString *errorStr = [NSString stringWithFormat:@"请在系统设置->隐私->照片中允许 "%@" 使用照片。",
      	                              [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleNameKey]];
      	        
      	        [[[UIAlertView alloc] initWithTitle:@"读取失败"
      	                                    message:errorStr
      	                                   delegate:nil
      	                          cancelButtonTitle:@"确定"
      	                          otherButtonTitles:nil] show];
      	    }
      	}
      	
      	// 获取选中的图片,imagePickerController 协议方法
      	- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
      	    
      	    // 获取选择的图片
      	    UIImage *image = info[UIImagePickerControllerOriginalImage];
      	    
      	    // 识别图片中的二维码
      	    NSString *resultString = [self recognizeQRCodeFromImage:image];
      	    
      	    // 输出扫描字符串
      	    [[[UIAlertView alloc] initWithTitle:@"读取成功"
      	                                message:resultString
      	                               delegate:nil
      	                      cancelButtonTitle:@"确定"
      	                      otherButtonTitles:nil] show];
      	    
      	    // 返回
      	    [picker dismissViewControllerAnimated:YES completion:nil];
      	}
      	
      	// 识别图片中的二维码
      	- (NSString *)recognizeQRCodeFromImage:(UIImage *)image {
      	    
      	    CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
      	    
      	    // 初始化扫描仪,设置识别类型和识别质量
      	    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
      	                                              context:nil
      	                                              options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
      	    
      	    // 扫描获取的特征组
      	    NSArray *features = [detector featuresInImage:ciImage];
      	    
      	    if (features.count >= 1) {
      	        
      	        // 获取扫描结果
      	        CIQRCodeFeature *feature = [features objectAtIndex:0];
      	        NSString *resultString = feature.messageString;
      	        
      	        return resultString;
      	        
      	    } else {
      	    
      	        return @"该图片不包含二维码";
      	    }
      	}
      
    • 效果

      QRCode12 QRCode13

    2.3 长按识别二维码

    • 这个功能有很多的地方在用,最让人熟知的我想便是微信了,其实实现方法还是很简单的。

      	// 创建图片,添加长按手势
      	- (void)recognizeQRCode {
      	    
      	    CGFloat margin = 50;
      	    CGRect scanFrame = CGRectMake(margin,
      	                                  margin + 20,
      	                                  self.view.bounds.size.width - margin * 2,
      	                                  self.view.bounds.size.width - margin * 2);
      	    
      	    UIImageView *imageView = [[UIImageView alloc] initWithFrame:scanFrame];
      	    imageView.image = [UIImage imageNamed:@"demo"];
      	    
      	    imageView.userInteractionEnabled = YES;
      	    
      	    [self.view addSubview:imageView];
      	    
      	    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self 
      	                                                                                            action:@selector(dealLongPress:)];
      	    [imageView addGestureRecognizer:longPress];
      	}
      	
      	// 处理长按手势,识别图片中的二维码
      	- (void)dealLongPress:(UIGestureRecognizer *)gesture {
      	    
      	    if (gesture.state == UIGestureRecognizerStateBegan) {
      	        
      	        UIImageView *pressedImageView = (UIImageView *)gesture.view;
      	        
      	        if (pressedImageView.image) {
      	            
      	            // 识别图片中的二维码
      	            NSString *resultString = [self recognizeQRCodeFromImage:pressedImageView.image];
      	            
      	            // 输出扫描字符串
      	            [[[UIAlertView alloc] initWithTitle:@"识别成功"
      	                                        message:resultString
      	                                       delegate:nil
      	                              cancelButtonTitle:@"确定"
      	                              otherButtonTitles:nil] show];
      	            
      	        } else {
      	            [[[UIAlertView alloc] initWithTitle:@"识别失败"
      	                                        message:@"该图片不包含二维码"
      	                                       delegate:nil
      	                              cancelButtonTitle:@"确定"
      	                              otherButtonTitles:nil] show];
      	        }
      	    }
      	}
      	
      	// 识别图片中的二维码
      	- (NSString *)recognizeQRCodeFromImage:(UIImage *)image {
      	    
      	    CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
      	    
      	    // 初始化扫描仪,设置识别类型和识别质量
      	    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
      	                                              context:nil
      	                                              options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
      	    
      	    // 扫描获取的特征组
      	    NSArray *features = [detector featuresInImage:ciImage];
      	    
      	    if (features.count >= 1) {
      	        
      	        // 获取扫描结果
      	        CIQRCodeFeature *feature = [features objectAtIndex:0];
      	        NSString *resultString = feature.messageString;
      	        
      	        return resultString;
      	        
      	    } else {
      	        
      	        return @"该图片不包含二维码";
      	    }
      	}
      
    • 效果

      QRCode14 QRCode15

    2.4 生成二维码

    • 生成二维码,其实也是用到 CoreImage,但是步骤繁琐一些,代码如下

      	// 创建 ImageView,存放生成的二维码
      	- (void)createQRCode {
      	    
      	    CGFloat margin = 50;
      	    CGRect frame = CGRectMake(margin,
      	                              margin + 20,
      	                              self.view.bounds.size.width - margin * 2,
      	                              self.view.bounds.size.width - margin * 2);
      	    
      	    UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
      	    [self.view addSubview:imageView];
      	    
      	    // 生成二维码
      	    [self createQRCodeToImageView:imageView
      	                       fromString:@"qianchia"
      	                         withIcon:[UIImage imageNamed:@"demo1"]
      	                        withColor:[UIColor redColor]];
      	}
      	
      	// 生成二维码
      	- (void)createQRCodeToImageView:(UIImageView *)imageView
      	                     fromString:(NSString *)inputString
      	                       withIcon:(UIImage *)icon
      	                      withColor:(UIColor *)color {
      	    
      	    // 创建过滤器
      	    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
      	    
      	    // 恢复默认
      	    [filter setDefaults];
      	    
      	    // 给过滤器添加数据
      	    NSData *data = [inputString dataUsingEncoding:NSUTF8StringEncoding];
      	    
      	    // 通过 KVO 设置滤镜 inputMessage 数据
      	    [filter setValue:data forKey:@"inputMessage"];
      	    
      	    // 设置二维码颜色
      	    UIColor *onColor = color ? : [UIColor blackColor];
      	    UIColor *offColor = [UIColor whiteColor];
      	    
      	    CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"
      	                                       keysAndValues:@"inputImage", filter.outputImage,
      	                                                     @"inputColor0", [CIColor colorWithCGColor:onColor.CGColor],
      	                                                     @"inputColor1", [CIColor colorWithCGColor:offColor.CGColor],
      	                                                     nil];
      	    
      	    // 获取输出的二维码
      	    CIImage *outputImage = colorFilter.outputImage;
      	    // CIImage *outputImage = [filter outputImage];
      	    
      	    CIContext *context = [CIContext contextWithOptions:nil];
      	    CGImageRef cgImage = [context createCGImage:outputImage
      	                                       fromRect:[outputImage extent]];
      	    
      	    // 将 CIImage 转换成 UIImage,并放大显示
      	    UIImage *qrImage = [UIImage imageWithCGImage:cgImage
      	                                         scale:1.0
      	                                   orientation:UIImageOrientationUp];
      	
      	    // 重绘 UIImage,默认情况下生成的图片比较模糊
      	    CGFloat scale = 100;
      	    CGFloat width = qrImage.size.width * scale;
      	    CGFloat height = qrImage.size.height * scale;
      	    
      	    UIGraphicsBeginImageContext(CGSizeMake(width, height));
      	    CGContextRef context1 = UIGraphicsGetCurrentContext();
      	    CGContextSetInterpolationQuality(context1, kCGInterpolationNone);
      	    [qrImage drawInRect:CGRectMake(0, 0, width, height)];
      	    qrImage = UIGraphicsGetImageFromCurrentImageContext();
      	    UIGraphicsEndImageContext();
      	    CGImageRelease(cgImage);
      	    
      	    // 添加头像
      	    
      	    if (icon) {
      	        UIGraphicsBeginImageContext(qrImage.size);
      	        [qrImage drawInRect:CGRectMake(0, 0, qrImage.size.width, qrImage.size.height)];
      	        
      	        // 设置头像大小
      	        CGFloat scale = 5;
      	        CGFloat width = qrImage.size.width / scale;
      	        CGFloat height = qrImage.size.height / scale;
      	        CGFloat x = (qrImage.size.width - width) / 2;
      	        CGFloat y = (qrImage.size.height - height) / 2;
      	        [icon drawInRect:CGRectMake( x,  y, width, height)];
      	        
      	        UIImage *newImage =  UIGraphicsGetImageFromCurrentImageContext();
      	        UIGraphicsEndImageContext();
      	        
      	        imageView.image = newImage;
      	        
      	    } else {
      	        imageView.image = qrImage;
      	    }
      	}
      
    • 效果

      QRCode16 QRCode17

    2.5 对原生二维码的封装

    • 具体实现代码见 GitHub 源码 QExtension

      	// 包含头文件
      	#import "QExtension.h"
      
    • 扫描/识别二维码

      	// 创建二维码扫描视图控制器
      	QQRCode *qrCode = [QQRCode q_qrCodeWithResult:^(BOOL isSucceed, NSString *result) {
      	    
      	    if (isSucceed) {
      	        
      	        [[[UIAlertView alloc] initWithTitle:@"Succeed"
      	                                    message:result
      	                                   delegate:nil
      	                          cancelButtonTitle:@"确定"
      	                          otherButtonTitles:nil] show];
      	        
      	    } else {
      	        
      	        [[[UIAlertView alloc] initWithTitle:@"Failed"
      	                                    message:result
      	                                   delegate:nil
      	                          cancelButtonTitle:@"确定"
      	                          otherButtonTitles:nil] show];
      	    }
      	}];
      	    
      	// 设置我的二维码信息
      	qrCode.myQRCodeInfo = @"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X";
      	qrCode.headIcon = [UIImage imageNamed:@"demo6"];
      	    
      	// 打开扫描视图控制器
      	[self presentViewController:qrCode animated:YES completion:nil];
      
      • 效果

        QRCode18 QRCode19

        QRCode20 QRCode21

    • 识别二维码

      	// 创建图片,添加长按手势
      	self.imageView.image = [UIImage imageNamed:@"demo4"];
      	    
      	UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(dealLongPress:)];
      	[self.imageView addGestureRecognizer:longPress];
      
      	// 处理长按手势,识别图片中的二维码
      	- (void)dealLongPress:(UIGestureRecognizer *)gesture {
      	    
      	    if (gesture.state == UIGestureRecognizerStateBegan) {
      	        
      	        UIImageView *pressedImageView = (UIImageView *)gesture.view;
      	        UIImage *image = pressedImageView.image;
      	        
      	        // 识别图片中的二维码
      	        NSString *result = [image q_stringByRecognizeQRCode];
      	        
      	        [[[UIAlertView alloc] initWithTitle:@"Succeed"
      	                                    message:result
      	                                   delegate:nil
      	                          cancelButtonTitle:@"确定"
      	                          otherButtonTitles:nil] show];
      	    }
      	}
      
      • 效果

        QRCode23

    • 生成二维码

      	// 生成普通的二维码
      	UIImage *qrImage = [UIImage q_imageWithQRCodeFromString:@"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X"
      	                                               headIcon:nil
      	                                                  color:nil
      	                                              backColor:nil];
      	    
      	// 生成带头像的二维码
      	UIImage *qrImage = [UIImage q_imageWithQRCodeFromString:@"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X"
      	                                               headIcon:[UIImage imageNamed:@"demo6"]
      	                                                  color:[UIColor blackColor]
      	                                              backColor:[UIColor whiteColor]];
      
      	// 生成指定图片大小的二维码
      	UIImage *qrImage = [UIImage q_imageWithQRCodeFromString:@"http://weixin.qq.com/r/xUqbg1-ENgJJrRvg9x-X"
      	                                              imageSize:CGSizeMake(2048, 2048)
      	                                               headIcon:[UIImage imageNamed:@"demo6"]
      	                                              headFrame:CGRectMake(819, 819, 410, 410)
      	                                                  color:nil
      	                                              backColor:nil];
      
      • 效果

        QRCode28 QRCode22

    2.6 对原生条形码的封装

    • 具体实现代码见 GitHub 源码 QExtension

      	// 包含头文件
      	#import "QExtension.h"
      
    • 扫描条形码

      • 同上面 2.5 的 "扫描/识别二维码"。
    • 生成条形码

      	
      	// 生成条形码
      	UIImage *qrImage = [UIImage q_imageWithBarCodeFromString:@"cnblogs: QianChia"
      	                                                   color:nil
      	                                               backColor:nil];
      	
      	// 生成指定图片大小的条形码
      	UIImage *qrImage = [UIImage q_imageWithBarCodeFromString:@"cnblogs: QianChia"
      	                                               imageSize:CGSizeMake(1024, 512)
      	                                                   color:[UIColor blueColor]
      	                                               backColor:[UIColor redColor]];
      	
      
      • 效果

        QRCode26 QRCode27

    3、ZBarSDK 二维码使用

    • 使用 ZBarSDK,可以扫描条形码和二维码。

    • 配置

      • 1、添加 SDK 的依赖库和框架。在 项目设置 => TARGETS => Build Phases => Link Binary With Libraries 中依次添加以下库或框架:

        	AVFoundation.framework
        	CoreMedia.framework
        	CoreVideo.framework
        	QuartzCore.framework
        	libiconv.tbd
        

        QRCode1

      • 2、由于 ZBarSDK 不支持 Bitcode,需要在 Xcode 的项目设置 => TARGETS => Build Settings => Build Options => Enable Bitcode 的值设置为 NO,否则无法进行真机调试。

        QRCode2

      • 3、在 iOS8 + 系统中使用相机需要在 Info.plist 中添加 Privacy - Camera Usage Description,并设置其值。

        QRCode3

      • 4、在需要使用 ZBarSDK 的文件中

        	// 包含头文件
        	#import "ZBarSDK.h"
        
        	// 遵守协议
        	<ZBarReaderViewDelegate>
        
    • 创建扫描

      	// 声明扫描视图
      	@property (nonatomic, strong) ZBarReaderView *scanView;
      
      	// 实例化扫描视图
      	self.scanView = [[ZBarReaderView alloc] init];
      	    
      	// 设置扫描视图的位置尺寸
      	float width = self.view.bounds.size.width - 40;
      	self.scanView.frame = CGRectMake(20, 30, width, width);
      	    
      	// 设置代理人
      	self.scanView.readerDelegate = self;
      	    
      	// 添加扫描视图
      	[self.view addSubview:self.scanView];
      	    
      	// 关闭闪光灯
      	self.scanView.torchMode = 0;
      	    
      	// 开始扫描
      	[self.scanView start];
      
    • 获取扫描结果

      	// ZBarReaderViewDelegate 协议方法
      	- (void)readerView:(ZBarReaderView *)readerView didReadSymbols:(ZBarSymbolSet *)symbols fromImage:(UIImage *)image {
      	    
      		for (ZBarSymbol *symbol in symbols) {
      			    
      			// 获取扫描结果
      			NSString *scanString = symbol.data;
      			    
      			// 显示扫描结果
      			self.scanResult.text = scanString;
      		}
      		    
      		// 停止扫描
      		[self.scanView stop];
      	}
      
    • 效果

      QRCode6 QRCode7

    4、ZCZBarSDK 二维码使用

    • 使用 ZCZBarSDK,可以扫描条形码和二维码。

    • 配置

      • 1、添加 SDK 的依赖库和框架。在 项目设置 => TARGETS => Build Phases => Link Binary With Libraries 中依次添加以下库或框架:

        	libiconv.tbd
        

        QRCode4

      • 2、由于 ZCZBarSDK 不支持 Bitcode,需要在 Xcode 的项目设置 => TARGETS => Build Settings => Build Options => Enable Bitcode 的值设置为 NO,否则无法进行真机调试。

        QRCode2

      • 3、在 iOS8 + 系统中使用相机需要在 Info.plist 中添加 Privacy - Camera Usage Description,并设置其值。使用相册需要在 Info.plist 中添加 Privacy - Photo Library Usage Description,并设置其值。

        QRCode5

      • 4、在需要使用 ZCZBarSDK 的文件中

        	// 包含头文件
        	#import "ZCZBarViewController.h"
        
    • 生成二维码

      	// 将字符串 self.detailTF.text 中的内容生成的二维码存放到 ImageView(self.codeImageView)中。
      
      	if (self.detailTF.text.length != 0) {
          
          	[ZCZBarViewController createImageWithImageView:self.codeImageView String:self.detailTF.text Scale:100];
      	}
      
    • 扫描二维码

      	// isQRCode: 是否关闭条形码扫描,专门扫描二维码。
      
      	ZCZBarViewController *zzvc = [[ZCZBarViewController alloc] initWithIsQRCode:NO Block:^(NSString *result, BOOL isSucceed) {
          
          	if (isSucceed) {
              
              	self.scanResult.text = [NSString stringWithFormat:@"%@", result];
          	}
      	}];
      
      	// 打开扫描视图控制器
      	[self presentViewController:zzvc animated:YES completion:nil];
      
    • 效果

      QRCode8 QRCode9

  • 相关阅读:
    链式结构(案例)
    基于JDK动态代理实现的接口链式调用(Fluent Interface)工具
    理解 OpenStack 高可用(HA)(3):Neutron 分布式虚拟路由(Neutron Distributed Virtual Routing)
    理解 OpenStack 高可用(HA)(2):Neutron L3 Agent HA 之 虚拟路由冗余协议(VRRP)
    Neutron 理解 (9): OpenStack 是如何实现 Neutron 网络 和 Nova虚机 防火墙的 [How Nova Implements Security Group and How Neutron Implements Virtual Firewall]
    Neutron 理解 (8): Neutron 是如何实现虚机防火墙的 [How Neutron Implements Security Group]
    Neutron 理解 (6): Neutron 是怎么实现虚拟三层网络的 [How Neutron implements virtual L3 network]
    Neutron 理解 (7): Neutron 是如何实现负载均衡器虚拟化的 [LBaaS V1 in Juno]
    Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population]
    Neutron 理解 (3): Open vSwitch + GRE/VxLAN 组网 [Netruon Open vSwitch + GRE/VxLAN Virutal Network]
  • 原文地址:https://www.cnblogs.com/QianChia/p/6213466.html
Copyright © 2020-2023  润新知