zoukankan      html  css  js  c++  java
  • 扫描二维码、条形码,生成二维码


    title: iOS二维码操作
    date: 2016-05-11 16:51:31

    iOS-ScanningCode

    功能:扫描二维码、条形码,生成二维码。具体使用请看项目。github地址 喜欢的朋友们给个星星吧。萌萌哒。

    • Image Displey(图片展示)
    图片名称 图片名称 图片名称 图片名称

    使用方法

    • 首先,你需要把项目中的XYLScaningCodeKit文件夹拖拽到你的项目任意位置,然后就可以开始使用了。

    • 添加二维码界面

      假如你需要在项目中需要使用生成二维码的功能,仅仅需要引入头文件和创建二维码视图并添加就可以了。例如这样:

    #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];
    }
    
    
    • 添加扫描二维码、条形码功能

      假如你需要使用扫码的功能,那代码稍微多一点点,多的部分就是开始扫码、读取扫码结果、处理扫码结果那部分。

      同样的,你也需要引入上面的头文件;

      然后就是一些逻辑了,不用太担心,因为我会有很多的注释,而且后面还会详细分析。代码如下:

    
    #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地址

  • 相关阅读:
    oracle之sqlplus讲解
    oracle数据库--启动和关闭
    linux下使用SSL代理(SSLedge)
    Titanium系列--利用js动态获取当前时间
    Titanium系列--利用Titanium开发android App实战总结
    Titanium系列--我常用的Titanium的快捷键(持续更新中。。)
    Titanium系列--安装Titanium Studio 中的Android SDK,JDK以及环境变量的配置(二)
    Titanium系列--Titanium的简介、Titanium Studio安装和配置(一)
    Happymenu新的开始
    对IEnumerable<T>和IQueryable<T>的一点见解
  • 原文地址:https://www.cnblogs.com/66it/p/5482753.html
Copyright © 2011-2022 走看看