zoukankan      html  css  js  c++  java
  • 系统自带二维码扫一扫

    因为个人项目是导航栏点击事件跳转到扫一扫控制器,所以下面的控制器里面会有导航栏

    View.h里面

    #import <UIKit/UIKit.h>

    @protocol QRCodeReaderViewDelegate <NSObject>

    - (void)readerScanResult:(NSString *)result;

    @end

    @interface QRCodeReaderView : UIView

    @property (nonatomic, weak) id<QRCodeReaderViewDelegate> delegate;

    @property (nonatomic,copy)UIImageView * readLineView;

    @property (nonatomic,assign)BOOL is_Anmotion;

    @property (nonatomic,assign)BOOL is_AnmotionFinished;

    //开启关闭扫描

    - (void)start;

    - (void)stop;

    - (void)loopDrawLine;//初始化扫描线

    @end

    View.m里面

    #import "QRCodeReaderView.h"

    #import <AVFoundation/AVFoundation.h>

    #define DeviceMaxHeight ([UIScreen mainScreen].bounds.size.height)

    #define DeviceMaxWidth ([UIScreen mainScreen].bounds.size.width)

    #define widthRate DeviceMaxWidth/320

    #define contentTitleColorStr @"666666" //正文颜色较深

    @interface QRCodeReaderView ()<AVCaptureMetadataOutputObjectsDelegate>

    {

        AVCaptureSession * session;

        NSTimer * countTime;

    }

    @property (nonatomic, strong) CAShapeLayer *overlay;

    @end

    @implementation QRCodeReaderView

    - (id)initWithFrame:(CGRect)frame

    {

        if ((self = [super initWithFrame:frame])) {

            [self instanceDevice];

      }

      return self;

    }

    - (void)instanceDevice

    {

        //扫描区域(一般UI会提供中间透明四周带样式的图片这就是扫描边框)

        UIImage *hbImage=[UIImage imageNamed:@"fktx_2x01"];

        UIImageView * scanZomeBack=[[UIImageView alloc] init];

        scanZomeBack.backgroundColor = [UIColor clearColor];

        scanZomeBack.layer.borderColor = [UIColor clearColor].CGColor;

    //    scanZomeBack.layer.borderWidth = 0;

        scanZomeBack.image = hbImage;

        //添加一个背景图片

        CGRect mImagerect = CGRectMake(60*widthRate, (DeviceMaxHeight-200*widthRate)/2, 200*widthRate, 200*widthRate);

        [scanZomeBack setFrame:mImagerect];

        CGRect scanCrop=[self getScanCrop:mImagerect readerViewBounds:self.frame];

        [self addSubview:scanZomeBack];

        //获取摄像设备

        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 = scanCrop;

        

        //初始化链接对象

        session = [[AVCaptureSession alloc]init];

        //高质量采集率

        [session setSessionPreset:AVCaptureSessionPresetHigh];

        if (input) {

            [session addInput:input];

        }

        if (output) {

            [session addOutput:output];

            //设置扫码支持的编码格式(如下设置条形码和二维码兼容)

            NSMutableArray *a = [[NSMutableArray alloc] init];

            if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]) {

                [a addObject:AVMetadataObjectTypeQRCode];

            }

            if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeEAN13Code]) {

                [a addObject:AVMetadataObjectTypeEAN13Code];

            }

            if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeEAN8Code]) {

                [a addObject:AVMetadataObjectTypeEAN8Code];

            }

            if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeCode128Code]) {

                [a addObject:AVMetadataObjectTypeCode128Code];

            }

            output.metadataObjectTypes=a;

        }

        

        AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];

        layer.videoGravity=AVLayerVideoGravityResizeAspectFill;

        layer.frame=self.layer.bounds;

        [self.layer insertSublayer:layer atIndex:0];

        

        [self setOverlayPickerView:self];

        

        //开始捕获

        [session startRunning];

        

        

    }

    -(void)loopDrawLine

    {

        _is_AnmotionFinished = NO;

        CGRect rect = CGRectMake(60*widthRate, (DeviceMaxHeight-200*widthRate)/2, 200*widthRate, 2);

        if (_readLineView) {

            _readLineView.alpha = 1;

            _readLineView.frame = rect;

            _readLineView.backgroundColor = FZColor(110, 185, 43);

        }

        else{

            _readLineView = [[UIImageView alloc] initWithFrame:rect];

           //设置扫面线背景图片

            [_readLineView setImage:[UIImage imageNamed:@"scanLine"]];

            [self addSubview:_readLineView];

        }

        

        [UIView animateWithDuration:1.5 animations:^{

            //修改fream的代码写在这里,扫描线有上下滑动效果

            _readLineView.frame =CGRectMake(60*widthRate, (DeviceMaxHeight-200*widthRate)/2+200*widthRate-5, 200*widthRate, 2);

        } completion:^(BOOL finished) {

            if (!_is_Anmotion) {

                [self loopDrawLine];

            }

            _is_AnmotionFinished = YES;

        }];

    }

    - (void)setOverlayPickerView:(QRCodeReaderView *)reader

    {

        

        CGFloat wid = 60*widthRate;

        CGFloat heih = (DeviceMaxHeight - 200*widthRate)/2;

        

        //最上部view

        UIView* upView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, DeviceMaxWidth, heih)];

        [reader addSubview:upView];

        upView.alpha = 0.4;

        upView.backgroundColor = [UIColor blackColor];

        

        

        

        //左侧的view

        UIView * cLeftView = [[UIView alloc] initWithFrame:CGRectMake(0, heih, wid, 200*widthRate)];

        cLeftView.alpha = 0.4;

        cLeftView.backgroundColor = [UIColor blackColor];

        [reader addSubview:cLeftView];

        

        //右侧的view

        UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(DeviceMaxWidth-wid, heih, wid, 200*widthRate)];

        rightView.backgroundColor = [UIColor blackColor];

        rightView.alpha = 0.4;

        [reader addSubview:rightView];

        

        //底部view

        UIView * downView = [[UIView alloc] initWithFrame:CGRectMake(0, heih+200*widthRate, DeviceMaxWidth, DeviceMaxHeight - heih-200*widthRate)];

        downView.backgroundColor = [UIColor blackColor];

        downView.alpha = 0.4;

        [reader addSubview:downView];

        

        //用于说明的label

        UILabel * labIntroudction= [[UILabel alloc] init];

        labIntroudction.backgroundColor = [UIColor clearColor];

        labIntroudction.frame=CGRectMake(0, (heih-64-50*widthRate)/2-10, DeviceMaxWidth, 50*widthRate);

        labIntroudction.textAlignment = NSTextAlignmentCenter;

        labIntroudction.textColor=[UIColor whiteColor];

        labIntroudction.text=@"请将二维码/条形码放入框内,即可自动扫描";

        labIntroudction.font = [UIFont boldSystemFontOfSize:14];

        labIntroudction.textColor = FZColor(110, 185, 43);

        [downView addSubview:labIntroudction];

        

    //    //开关灯button(这里是开灯按钮,我的项目里面没用到,所以注释掉)

    //    UIButton * turnBtn = [UIButton buttonWithType:UIButtonTypeCustom];

    //    turnBtn.backgroundColor = [UIColor clearColor];

    //    [turnBtn setBackgroundImage:[UIImage imageNamed:@"lightSelect"] forState:UIControlStateNormal];

    //    [turnBtn setBackgroundImage:[UIImage imageNamed:@"lightNormal"] forState:UIControlStateSelected];

    //    turnBtn.frame=CGRectMake((DeviceMaxWidth-50*widthRate)/2, (CGRectGetHeight(downView.frame)-50*widthRate)/2, 50*widthRate, 50*widthRate);

    //    [turnBtn addTarget:self action:@selector(turnBtnEvent:) forControlEvents:UIControlEventTouchUpInside];

    //    [downView addSubview:turnBtn];

        

    }

    - (void)turnBtnEvent:(UIButton *)button_

    {

        button_.selected = !button_.selected;

        if (button_.selected) {

            [self turnTorchOn:YES];

        }

        else{

            [self turnTorchOn:NO];

        }

        

    }

    - (void)turnTorchOn:(bool)on

    {

        Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");

        if (captureDeviceClass != nil) {

            AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

            

            if ([device hasTorch] && [device hasFlash]){

                

                [device lockForConfiguration:nil];

                if (on) {

                    [device setTorchMode:AVCaptureTorchModeOn];

                    [device setFlashMode:AVCaptureFlashModeOn];

                    

                } else {

                    [device setTorchMode:AVCaptureTorchModeOff];

                    [device setFlashMode:AVCaptureFlashModeOff];

                }

                [device unlockForConfiguration];

            }

        }

    }

    -(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds

    {

        

        CGFloat x,y,width,height;

        

    //    width = (CGFloat)(rect.size.height+10)/readerViewBounds.size.height;

    //    

    //    height = (CGFloat)(rect.size.width-50)/readerViewBounds.size.width;

    //    

    //    x = (1-width)/2;

    //    y = (1-height)/2;

        

        x = (CGRectGetHeight(readerViewBounds)-CGRectGetHeight(rect))/2/CGRectGetHeight(readerViewBounds);

        y = (CGRectGetWidth(readerViewBounds)-CGRectGetWidth(rect))/2/CGRectGetWidth(readerViewBounds);

        width = CGRectGetHeight(rect)/CGRectGetHeight(readerViewBounds);

        height = CGRectGetWidth(rect)/CGRectGetWidth(readerViewBounds);

        

        return CGRectMake(x, y, width, height);

        

    }

    - (void)start

    {

        [session startRunning];

    }

    - (void)stop

    {

        [session stopRunning];

    }

    #pragma mark - 扫描结果

    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection

    {

        if (metadataObjects && metadataObjects.count>0) {

            AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];

            //输出扫描字符串

            if (_delegate && [_delegate respondsToSelector:@selector(readerScanResult:)]) {

                [_delegate readerScanResult:metadataObject.stringValue];

            }

        }

    }

    #pragma mark - 颜色

    //获取颜色

    - (UIColor *)colorFromHexRGB:(NSString *)inColorString

    {

        UIColor *result = nil;

        unsigned int colorCode = 0;

        unsigned char redByte, greenByte, blueByte;

        

        if (nil != inColorString)

        {

            NSScanner *scanner = [NSScanner scannerWithString:inColorString];

            (void) [scanner scanHexInt:&colorCode]; // ignore error

        }

        redByte = (unsigned char) (colorCode >> 16);

        greenByte = (unsigned char) (colorCode >> 8);

        blueByte = (unsigned char) (colorCode); // masks off high bits

        result = [UIColor

                  colorWithRed: (float)redByte / 0xff

                  green: (float)greenByte/ 0xff

                  blue: (float)blueByte / 0xff

                  alpha:1.0];

        return result;

    }

    @end

    ViewController.m里面(.h里面无代码)

    //

    //  SWeepViewController.m

    //  美邻家居

    //

    //  Created by 付智鹏 on 16/2/23.

    //  Copyright © 2016年 付智鹏. All rights reserved.

    //

    #import "SWeepViewController.h"

    #import "QRCodeReaderView.h"

    #import <AVFoundation/AVFoundation.h>

    #import <AudioToolbox/AudioToolbox.h>

    #define DeviceMaxHeight ([UIScreen mainScreen].bounds.size.height)

    #define DeviceMaxWidth ([UIScreen mainScreen].bounds.size.width)

    #define widthRate DeviceMaxWidth/320

    #define IOS8 ([[UIDevice currentDevice].systemVersion intValue] >= 8 ? YES : NO)

    @interface SWeepViewController ()<QRCodeReaderViewDelegate,AVCaptureMetadataOutputObjectsDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIAlertViewDelegate>

    {

    QRCodeReaderView * readview;//二维码扫描对象

    BOOL isFirst;//第一次进入该页面

    BOOL isPush;//跳转到下一级页面

    }

    @property (strong, nonatomic) CIDetector *detector;

    @end

    @implementation SWeepViewController

    -(void)viewDidLoad

    {

        //右侧导航栏按钮(个人项目中是导航栏上按钮推出此控制器,所以这里会有导航栏的设置,不添加导航栏的可以忽略)

     //   UIButton *rightbutton = [UIButton rightbuttonwithtitleName:@"相册"target:self //action:@selector(alumbBtnEvent)];

     //   UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc]initWithCustomView:rightbutton];

    //    self.navigationItem.rightBarButtonItem = rightBtn;

        isFirst = YES;

        isPush = NO;

        [self InitScan];

    }

    - (void)didReceiveMemoryWarning {

        [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    }

    #pragma mark 初始化扫描

    - (void)InitScan

    {

        if (readview) {

            [readview removeFromSuperview];

            readview = nil;

        }

        

        readview = [[QRCodeReaderView alloc]initWithFrame:CGRectMake(0, 0, DeviceMaxWidth, DeviceMaxHeight)];

        readview.is_AnmotionFinished = YES;

        readview.backgroundColor = [UIColor clearColor];

        readview.delegate = self;

        readview.alpha = 0;

        

        [self.view addSubview:readview];

        

        [UIView animateWithDuration:0.5 animations:^{

            readview.alpha = 1;

        }completion:^(BOOL finished) {

            

        }];

        

    }

    #pragma mark - 相册

    - (void)alumbBtnEvent

    {

        

        self.detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];

        

        if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { //判断设备是否支持相册

            

            if (IOS8) {

                UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"未开启访问相册权限,现在去开启!" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];

                alert.tag = 4;

                [alert show];

            }

            else{

                UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"设备不支持访问相册,请在设置->隐私->照片中进行设置!" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

                [alert show];

            }

            

            return;

        }

        

        isPush = YES;

        UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];

        mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

        mediaUI.mediaTypes = [UIImagePickerController         availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];

        mediaUI.allowsEditing = NO;

        mediaUI.delegate = self;

        [self presentViewController:mediaUI animated:YES completion:^{

            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];

        }];

        

        

    }

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

    {

        

        UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];

        if (!image){

            image = [info objectForKey:UIImagePickerControllerOriginalImage];

        }

        

        readview.is_Anmotion = YES;

        

        NSArray *features = [self.detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];

        if (features.count >=1) {

            

            [picker dismissViewControllerAnimated:YES completion:^{

                [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

                

                CIQRCodeFeature *feature = [features objectAtIndex:0];

                NSString *scannedResult = feature.messageString;

                //播放扫描二维码的声音

                SystemSoundID soundID;

                NSString *strSoundFile = [[NSBundle mainBundle] pathForResource:@"noticeMusic" ofType:@"wav"];

                AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:strSoundFile],&soundID);

                AudioServicesPlaySystemSound(soundID);

                

                [self accordingQcode:scannedResult];

            }];

            

        }

        else{

            UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:nil message:@"该图片没有包含一个二维码!" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

            [alertView show];

            

            [picker dismissViewControllerAnimated:YES completion:^{

                [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

                

                readview.is_Anmotion = NO;

                [readview start];

            }];

        }

    }

    - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker

    {

        [picker dismissViewControllerAnimated:YES completion:^{

            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

        }];

        

    }

    #pragma mark -QRCodeReaderViewDelegate

    - (void)readerScanResult:(NSString *)result

    {

        readview.is_Anmotion = YES;

        [readview stop];

        

        //播放扫描二维码的声音(注意:没有声音文件会崩溃,可以自己去网上下载)

        SystemSoundID soundID;

        NSString *strSoundFile = [[NSBundle mainBundle] pathForResource:@"noticeMusic" ofType:@"wav"];

        AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:strSoundFile],&soundID);

        AudioServicesPlaySystemSound(soundID);

        [self accordingQcode:result];

        

        [self performSelector:@selector(reStartScan) withObject:nil afterDelay:1.5];

    }

    #pragma mark - 扫描结果处理

    - (void)accordingQcode:(NSString *)str

    {

    //    UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"扫描结果" message:str delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

    //    [alertView show];

    }

    - (void)reStartScan

    {

        readview.is_Anmotion = NO;

        

        if (readview.is_AnmotionFinished) {

            [readview loopDrawLine];

        }

        

        [readview start];

    }

    #pragma mark - view

    - (void)viewWillAppear:(BOOL)animated

    {

        self.tabBarController.hidesBottomBarWhenPushed = YES;

        [super viewWillAppear:animated];

        

        if (isFirst || isPush) {

            if (readview) {

                [self reStartScan];

            }

        }

        

    }

    -(void)viewWillDisappear:(BOOL)animated{

        self.tabBarController.hidesBottomBarWhenPushed = NO;

    }

    - (void)viewDidDisappear:(BOOL)animated

    {

        [super viewDidDisappear:animated];

        

        if (readview) {

            [readview stop];

            readview.is_Anmotion = YES;

        }

        

    }

    - (void)viewDidAppear:(BOOL)animated

    {

        [super viewDidAppear:animated];

        

        if (isFirst) {

            isFirst = NO;

        }

        if (isPush) {

            isPush = NO;

        }

    }

    @end

  • 相关阅读:
    安卓 如何载入一个新窗口如何关闭窗口和向另一个窗口传值
    大数相加算法
    JsonTools
    数组、链表、哈希表
    JavaScript, JQuery事件委托
    前端移动端的适配
    JavaScript设置和获取cookie
    WCF、WebAPI、WebService之间的区别
    npm设置成淘宝镜像
    JQuery中 text()、html() 以及 val()以及innerText、innerHTML和value
  • 原文地址:https://www.cnblogs.com/FZP5/p/5289051.html
Copyright © 2011-2022 走看看