ios原生二維碼掃描識(shí)別

完整iOS二維碼掃描功能的實(shí)現(xiàn)

lhScanQCodeTest_免費(fèi)高速下載|百度網(wǎng)盤(pán)-分享無(wú)限制

功能頁(yè)面給掃一掃按鈕添加點(diǎn)擊事件進(jìn)行跳轉(zhuǎn)

lhScanQCodeViewController * sqVC = [[lhScanQCodeViewController alloc]init];

? ? UINavigationController * nVC = [[UINavigationController alloc]initWithRootViewController:sqVC];

? ? [self presentViewController:nVC animated:YES completion:^{ }];

邏輯處理? .h文件

#import@interface lhScanQCodeViewController : UIViewController

@end

邏輯處理.m文件

#import "lhScanQCodeViewController.h"#import "QRCodeReaderView.h"#import#import#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 lhScanQCodeViewController (){

? ? QRCodeReaderView * readview;//二維碼掃描對(duì)象


? ? BOOL isFirst;//第一次進(jìn)入該頁(yè)面

? ? BOOL isPush;//跳轉(zhuǎn)到下一級(jí)頁(yè)面

}

@property (strong, nonatomic) CIDetector *detector;

@end

@implementation lhScanQCodeViewController

- (void)viewDidLoad {

? ? [super viewDidLoad];

? ? // Do any additional setup after loading the view.

? ? self.title = @"掃描";

? ? self.view.backgroundColor = [UIColor whiteColor];


? ? UIBarButtonItem * rbbItem = [[UIBarButtonItem alloc]initWithTitle:@"相冊(cè)" style:UIBarButtonItemStyleDone target:self action:@selector(alumbBtnEvent)];

? ? self.navigationItem.rightBarButtonItem = rbbItem;


? ? UIBarButtonItem * lbbItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:self action:@selector(backButtonEvent)];

? ? self.navigationItem.leftBarButtonItem = lbbItem;


? ? isFirst = YES;

? ? isPush = NO;


? ? [self InitScan];

}

- (void)didReceiveMemoryWarning {

? ? [super didReceiveMemoryWarning];

? ? // Dispose of any resources that can be recreated.

}

#pragma mark - 返回

- (void)backButtonEvent

{

? ? [self dismissViewControllerAnimated:YES completion:^{


? ? }];

}

#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 - 相冊(cè)

- (void)alumbBtnEvent

{


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

? ? if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { //判斷設(shè)備是否支持相冊(cè)


? ? ? ? if (IOS8) {

? ? ? ? ? ? UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"未開(kāi)啟訪(fǎng)問(wèn)相冊(cè)權(quán)限,現(xiàn)在去開(kāi)啟!" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];

? ? ? ? ? ? alert.tag = 4;

? ? ? ? ? ? [alert show];

? ? ? ? }

? ? ? ? else{

? ? ? ? ? ? UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"設(shè)備不支持訪(fǎng)問(wèn)相冊(cè),請(qǐng)?jiān)谠O(shè)置->隱私->照片中進(jìn)行設(shè)置!" 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:@"提示" message:@"該圖片沒(méi)有包含一個(gè)二維碼!" 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 - 掃描結(jié)果處理

- (void)accordingQcode:(NSString *)str

{

? ? UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:@"掃描結(jié)果" 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

{

? ? [super viewWillAppear:animated];


? ? if (isFirst || isPush) {

? ? ? ? if (readview) {

? ? ? ? ? ? [self reStartScan];

? ? ? ? }

? ? }


}

- (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

界面的展示.H文件

#import/** * Simple view to display an overlay (a square) over the camera view. * @since 2.0.0 */@protocol QRCodeReaderViewDelegate- (void)readerScanResult:(NSString *)result;@end@interface QRCodeReaderView : UIView@property (nonatomic, weak) id delegate;

@property (nonatomic,copy)UIImageView * readLineView;

@property (nonatomic,assign)BOOL is_Anmotion;

@property (nonatomic,assign)BOOL is_AnmotionFinished;

//開(kāi)啟關(guān)閉掃描

- (void)start;

- (void)stop;

- (void)loopDrawLine;//初始化掃描線(xiàn)

@end

界面的.M文件

#import "QRCodeReaderView.h"#import#define DeviceMaxHeight ([UIScreen mainScreen].bounds.size.height)#define DeviceMaxWidth ([UIScreen mainScreen].bounds.size.width)#define widthRate DeviceMaxWidth/320#define contentTitleColorStr @"666666" //正文顏色較深@interface QRCodeReaderView (){

? ? 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

{

? ? //掃描區(qū)域

? ? UIImage *hbImage=[UIImage imageNamed:@"scanscanBg"];

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

? ? scanZomeBack.backgroundColor = [UIColor clearColor];

? ? scanZomeBack.layer.borderColor = [UIColor whiteColor].CGColor;

? ? scanZomeBack.layer.borderWidth = 2.5;

? ? scanZomeBack.image = hbImage;

? ? //添加一個(gè)背景圖片

? ? 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];


? ? //獲取攝像設(shè)備

? ? AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

? ? //創(chuàng)建輸入流

? ? AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];

? ? //創(chuàng)建輸出流

? ? AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];

? ? //設(shè)置代理 在主線(xiàn)程里刷新

? ? [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

? ? output.rectOfInterest = scanCrop;


? ? //初始化鏈接對(duì)象

? ? session = [[AVCaptureSession alloc]init];

? ? //高質(zhì)量采集率

? ? [session setSessionPreset:AVCaptureSessionPresetHigh];

? ? if (input) {

? ? ? ? [session addInput:input];

? ? }

? ? if (output) {

? ? ? ? [session addOutput:output];

? ? ? ? //設(shè)置掃碼支持的編碼格式(如下設(shè)置條形碼和二維碼兼容)

? ? ? ? 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];


? ? //開(kāi)始捕獲

? ? [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;

? ? }

? ? else{

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

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

? ? ? ? [self addSubview:_readLineView];

? ? }


? ? [UIView animateWithDuration:1.5 animations:^{

? ? ? ? //修改fream的代碼寫(xiě)在這里

? ? ? ? _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

? ? CGFloat alpha = 0.6;

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

? ? upView.alpha = alpha;

? ? upView.backgroundColor = [self colorFromHexRGB:contentTitleColorStr];

? ? [reader addSubview:upView];


? ? //用于說(shuō)明的label

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

? ? labIntroudction.backgroundColor = [UIColor clearColor];

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

? ? labIntroudction.textAlignment = NSTextAlignmentCenter;

? ? labIntroudction.textColor=[UIColor whiteColor];

? ? labIntroudction.text=@"請(qǐng)掃描XXXX支付二維碼";

? ? [upView addSubview:labIntroudction];


? ? //左側(cè)的view

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

? ? cLeftView.alpha = alpha;

? ? cLeftView.backgroundColor = [self colorFromHexRGB:contentTitleColorStr];

? ? [reader addSubview:cLeftView];


? ? //右側(cè)的view

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

? ? rightView.alpha = alpha;

? ? rightView.backgroundColor = [self colorFromHexRGB:contentTitleColorStr];

? ? [reader addSubview:rightView];


? ? //底部view

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

? ? downView.alpha = alpha;

? ? downView.backgroundColor = [self colorFromHexRGB:contentTitleColorStr];

? ? [reader addSubview:downView];


? ? //開(kāi)關(guān)燈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 - 掃描結(jié)果

- (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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 原文鏈接http://www.cnblogs.com/kenshincui/p/4186022.html 音頻在i...
    Hyman0819閱讀 21,828評(píng)論 4 74
  • 1、禁止手機(jī)睡眠[UIApplication sharedApplication].idleTimerDisabl...
    DingGa閱讀 1,144評(píng)論 1 6
  • CIDetector 這個(gè)api是蘋(píng)果在ios8之后提供的。所以用蘋(píng)果自帶的AVFundation掃描,如果從相冊(cè)...
    然亦傘閱讀 576評(píng)論 1 0
  • 近代國(guó)畫(huà)大師黃賓虹曾說(shuō):“唐畫(huà)如麴,宋畫(huà)如酒,元畫(huà)如醇,元代以下,漸如酒之加水,時(shí)代愈近,加水愈多,近日之畫(huà)已有水...
    半樵閱讀 602評(píng)論 10 20
  • 如果你想學(xué)點(diǎn)什么,就要善于搜索。而在這個(gè)時(shí)代里,最好的搜索工具就是Google。 以下介紹幾種常用的方法 1 使用...
    阿太哥閱讀 710評(píng)論 0 0