1. 程式人生 > >iOS 原生二維碼掃描

iOS 原生二維碼掃描

oca lac sig mediatype gate 5.0 項目 machine lec

直接上項目代碼

首先檢查相機權限  

AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (status == AVAuthorizationStatusRestricted || status == AVAuthorizationStatusDenied) {
    // 沒有授權訪問相機權限 提示
    return;
}


#import "QrCodeVC.h"
#import <AVFoundation/AVFoundation.h>
#import
<Masonry/Masonry.h> #import <pop/POP.h> #import "AppDelegate.h" #import "GoodsDetailVC.h" #import "WebViewVC.h" #define QRWH (ZKScreenW*283/375.0) #define TOP (ZKScreenH-QRWH)/2.0 #define LEFT (ZKScreenW-QRWH)/2.0 #define kScanRect CGRectMake(LEFT, TOP, QRWH, QRWH) #define kLineRect CGRectMake(LEFT+15, TOP, QRWH-30, 3) const
static CGFloat animationTime = 2.0f;//掃描時長 @interface QrCodeVC () <AVCaptureMetadataOutputObjectsDelegate> { CAShapeLayer *cropLayer; } @property (nonatomic, strong) AVCaptureDevice *device; @property (nonatomic, strong) AVCaptureDeviceInput *input; @property (nonatomic, strong) AVCaptureMetadataOutput
*output; @property (nonatomic, strong) AVCaptureSession *session; @property (nonatomic, strong) AVCaptureVideoPreviewLayer *preview; /** 二維碼View **/ @property (nonatomic, strong) UIImageView *qrImageView; @property (nonatomic, strong) UIImageView *animationImageV; @property (nonatomic, assign) BOOL animationUp; @property (nonatomic, strong) UILabel *messageLb; @end @implementation QrCodeVC - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (_session != nil) { [_session startRunning]; } self.animationImageV.hidden = NO; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // if (_session != nil) { // [_session stopRunning]; // } self.animationImageV.hidden = YES; } - (void)viewDidLoad { [super viewDidLoad]; // 初始化掃描UI [self initView]; // 初始化掃描二維碼 [self setupCamera]; } - (void)initView { UIView *bgView = [[UIView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:bgView]; bgView.backgroundColor = [UIColor clearColor]; cropLayer = [[CAShapeLayer alloc] init]; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, nil, kScanRect); CGPathAddRect(path, nil, self.view.bounds); [cropLayer setFillRule:kCAFillRuleEvenOdd]; [cropLayer setPath:path]; [cropLayer setFillColor:[[UIColor blackColor] colorWithAlphaComponent:0.3].CGColor]; [cropLayer setNeedsDisplay]; [bgView.layer addSublayer:cropLayer]; UIImageView *imageV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"qrCode_bg"]]; imageV.frame = kScanRect; [self.view addSubview:imageV]; _qrImageView = imageV; UIImageView *animationImageV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"qrCodeLine"]]; animationImageV.frame = kLineRect; animationImageV.contentMode = UIViewContentModeScaleAspectFill; [self.view addSubview:animationImageV]; _animationImageV = animationImageV; UILabel *messageLb = [[UILabel alloc] initWithFrame:CGRectMake(15, TOP-40, ZKScreenW-30, 20)]; messageLb.text = getStringByKey(@"string_key_1592"); messageLb.textAlignment = NSTextAlignmentCenter; messageLb.numberOfLines = 0; messageLb.font = [UIFont boldSystemFontOfSize:14]; messageLb.textColor = [UIColor whiteColor]; [self.view addSubview:messageLb]; UILabel *titleLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 30, ZKScreenW, 20)]; titleLb.text = getStringByKey(@"string_key_1593"); titleLb.textAlignment = NSTextAlignmentCenter; titleLb.font = [UIFont boldSystemFontOfSize:17]; titleLb.textColor = [UIColor whiteColor]; [self.view addSubview:titleLb]; UIButton *backBtn = [[UIButton alloc] init]; [backBtn setImage:[UIImage imageNamed:@"video_wirteBackArrow"] forState:UIControlStateNormal]; [backBtn addTarget:self action:@selector(clickBackBtn) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:backBtn]; [backBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.view.mas_top).with.offset(20); make.leading.equalTo(self.view.mas_leading); make.width.mas_equalTo(44); make.height.mas_equalTo(44); }]; } - (void)clickBackBtn { [self.navigationController popViewControllerAnimated:YES]; } - (CABasicAnimation *)qrAnimation { CGPoint starPoint = CGPointMake(_qrImageView.centerX , _qrImageView.mj_y+3); CGPoint endPoint = CGPointMake(_qrImageView.centerX, _qrImageView.mj_y+QRWH-3); CABasicAnimation*translation = [CABasicAnimation animationWithKeyPath:@"position"]; translation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; translation.fromValue = [NSValue valueWithCGPoint:starPoint]; translation.toValue = [NSValue valueWithCGPoint:endPoint]; translation.duration = animationTime; translation.repeatCount = CGFLOAT_MAX; translation.autoreverses = YES; translation.removedOnCompletion = NO; return translation; } - (void)setupCamera { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if (device==nil) { // 設備沒有攝像頭 // UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"設備沒有攝像頭" preferredStyle:UIAlertControllerStyleAlert]; // [alert addAction:[UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // // }]]; // [self presentViewController:alert animated:YES completion:nil]; return; } _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil]; _output = [[AVCaptureMetadataOutput alloc]init]; [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //設置掃描區域 CGFloat top = TOP/ZKScreenH; CGFloat left = LEFT/ZKScreenW; CGFloat width = QRWH/ZKScreenW; CGFloat height = QRWH/ZKScreenH; ///top 與 left 互換 width 與 height 互換 [_output setRectOfInterest:CGRectMake(top,left, height, width)]; // Session _session = [[AVCaptureSession alloc]init]; [_session setSessionPreset:AVCaptureSessionPresetHigh]; if ([_session canAddInput:self.input]) { [_session addInput:self.input]; } if ([_session canAddOutput:self.output]) { [_session addOutput:self.output]; } // 條碼類型 AVMetadataObjectTypeQRCode [_output setMetadataObjectTypes:[NSArray arrayWithObjects:AVMetadataObjectTypeQRCode, nil]]; // Preview _preview =[AVCaptureVideoPreviewLayer layerWithSession:_session]; _preview.videoGravity = AVLayerVideoGravityResizeAspectFill; _preview.frame =self.view.layer.bounds; [self.view.layer insertSublayer:_preview atIndex:0]; [_session startRunning]; [_animationImageV.layer addAnimation:[self qrAnimation] forKey:nil]; } #pragma mark AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { NSString *stringValue; if ([metadataObjects count] >0) { //停止掃描 [_session stopRunning]; AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0]; stringValue = metadataObject.stringValue; if (stringValue.length > 0) { if ([stringValue containsString:@"sheinlink://applink/"]) { // 調用deeplink跳轉頁面 AppDelegate *appDelegate=(AppDelegate*)[UIApplication sharedApplication].delegate; [appDelegate openWithUrl:[NSURL URLWithString:stringValue]]; } else if ([stringValue containsString:@"toApp"] && [stringValue containsString:@"goods_id="]) { // 商品詳情 NSRange sizeRange= [stringValue rangeOfString:@"goods_id="]; NSString *goodsId = [stringValue substringFromIndex:sizeRange.location+@"goods_id=".length]; if (goodsId) { GoodsInfo *goodsInfo=[[GoodsInfo alloc] init]; goodsInfo.goods_id=[goodsId intValue]; UIStoryboard *sb=[UIStoryboard storyboardWithName:@"Goods" bundle:[NSBundle mainBundle]]; GoodsDetailVC *vc=[sb instantiateViewControllerWithIdentifier:@"GoodsDetailVC"]; vc.goodsInfo=goodsInfo; [self.navigationController pushViewController:vc animated:YES]; } } else { // 跳轉到普通網頁 UIStoryboard *sb=[UIStoryboard storyboardWithName:@"Setting" bundle:[NSBundle mainBundle]]; WebViewVC *vc=[sb instantiateViewControllerWithIdentifier:@"WebViewVC"]; vc.titleText = @""; vc.url = stringValue; [self.navigationController pushViewController:vc animated:YES]; } } else { // 沒有獲取到url } } else { NSLog(@"無掃描信息"); return; } }

iOS 原生二維碼掃描