類似微信掃碼效果,會(huì)標(biāo)記識(shí)別到的二維碼震蒋,并且識(shí)別到多個(gè)二維碼時(shí)走孽,可以允許用戶點(diǎn)選敛腌。
二維碼坐標(biāo)解析步驟:
1攝像頭掃描
首先說明:攝像頭獲取的視頻流和屏幕尺寸比例不一定一樣,獲取的二維碼坐標(biāo)及角點(diǎn)是以視頻流的坐標(biāo)系為基準(zhǔn)的比例值(范圍0-1)搬男。
本次代碼以videoPreviewLayer(用于展示攝像頭捕獲的視頻流)frame設(shè)為全屏,setVideoGravity參數(shù)設(shè)為AVLayerVideoGravityResizeAspectFill為例進(jìn)行說明。
掃描代理方法返回的數(shù)據(jù)為AVMetadataMachineReadableCodeObject數(shù)組(若是設(shè)置為人臉掃描等其它模式祥绞,則返回對(duì)應(yīng)類型的數(shù)組)
AVMetadataMachineReadableCodeObject關(guān)鍵屬性:
type:數(shù)據(jù)類型(二維碼矾柜,條形碼等碼類型);
stringValue:二維碼或條形碼的值就谜;
bounds:二維碼在源視頻流對(duì)應(yīng)的幀圖像中的位置和大小怪蔑。
corners:二維碼的四個(gè)角的點(diǎn)坐標(biāo)。
其中bounds和corners的基準(zhǔn)坐標(biāo)系是視頻源中對(duì)應(yīng)的幀畫面坐標(biāo)系丧荐。
我們主要用corners來計(jì)算二維碼在videoPreviewLayer上顯示的位置及對(duì)應(yīng)的視圖坐標(biāo)系下的frame缆瓣。
然后添加透明遮罩層在對(duì)應(yīng)的位置添加按鈕及點(diǎn)擊事件。
計(jì)算位置的具體步驟為:
評(píng)論區(qū)有說系統(tǒng)自帶方法是可以直接計(jì)算frame的:transformedMetadataObjectForMetadataObject方法
有驗(yàn)證過的可以在評(píng)論區(qū)補(bǔ)充~
//在這個(gè)方法里面:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
AVMetadataObject *newObj = [connection.videoPreviewLayer transformedMetadataObjectForMetadataObject:obj];
//newObj.bounds 就是轉(zhuǎn)為app坐標(biāo)系的了虹统。
}
//connection
以上方法可用的話弓坞,下面這步驟可以不用看了。
1车荔,獲取差值渡冻。
此時(shí)4個(gè)角點(diǎn)坐標(biāo)已轉(zhuǎn)換完畢巍举,但是二維碼不一定與屏幕角度相同,通過角點(diǎn)計(jì)算出二維碼的長(zhǎng)方形范圍坐標(biāo)作為二維碼frame凝垛,并在其中心點(diǎn)添加按鈕:
具體可看方法:-(CGRect)makeFrameWithCodeObject:(AVMetadataMachineReadableCodeObject *)objc;
2,圖片選擇掃描:
圖片掃描返回的數(shù)據(jù)為:CIQRCodeFeature主要參數(shù):
messageString:碼值梦皮;
bounds:碼位置
其中bounds是二維碼在圖片坐標(biāo)系上的位置炭分,單位是像素,坐標(biāo)系方向受圖片方向影響届氢。
關(guān)于圖片方向:
uiimage方向?qū)傩詉mageOrientation:
typedef NS_ENUM(NSInteger, UIImageOrientation) {
UIImageOrientationUp, // default orientation
UIImageOrientationDown, // 180 deg rotation
UIImageOrientationLeft, // 90 deg CCW
UIImageOrientationRight, // 90 deg CW
UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
UIImageOrientationDownMirrored, // horizontal flip
UIImageOrientationLeftMirrored, // vertical flip
UIImageOrientationRightMirrored, // vertical flip
};
手機(jī)展示圖片時(shí)會(huì)受圖片方向影響欠窒,比如無論是橫持還是豎持甚至倒持手機(jī)拍攝一個(gè)“↑“,在相冊(cè)展示時(shí)箭頭都是朝上的。我們?cè)趇mageView展示時(shí)也是一樣岖妄。但是二維碼識(shí)別返回的數(shù)據(jù)中:
靠近音量調(diào)節(jié)的角為原點(diǎn)(0型将,0)。長(zhǎng)邊為X軸荐虐,短邊為Y軸七兜,二維碼的origin為靠近原點(diǎn)的角
所以需要坐標(biāo)系轉(zhuǎn)換。
默認(rèn)圖片拍攝的坐標(biāo)系為手機(jī)朝左橫持為下圖的樣子(即圖片方向?yàn)閁IImageOrientationUp的圖片福扬,是以下圖手持方向拍攝的)
正常豎屏展示的樣子(正常開發(fā)時(shí)的坐標(biāo)系)及二維碼frame.origin點(diǎn)為:(UIImageOrientationUp的圖片,在app內(nèi)展示的樣子铛碑,及我們需要的origin點(diǎn)的位置)
對(duì)比后狠裹,我們應(yīng)該要做Y軸反轉(zhuǎn)和比例縮放計(jì)算
y軸翻轉(zhuǎn)計(jì)算:圖片的H-二維碼的H-二維碼的y值。
在計(jì)算圖片縮放比列后就可以得出在正常坐標(biāo)系下二維碼在圖片的位置汽烦。
其它幾種拍照下的坐標(biāo)系示例:
可以看出:
UIImageOrientationRight方向的圖片需要XY交換撇吞,
UIImageOrientationDown方向的需要翻轉(zhuǎn)x值俗冻。
其他屬性可以類推。
另外帶鏡像屬性的圖片暫時(shí)沒有找到牍颈,未做測(cè)試。
代碼部分
.h:
#import <UIKit/UIKit.h>
typedef void(^ScanResultBlock)(NSString* result); //二維碼點(diǎn)選操作
typedef void(^ScanOutputs)(NSArray* results);//@[@{@"code":"",@"frame":@""}]
@interface XYQRScanViewController : UIViewController
@property (strong, nonatomic, readonly) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (assign, nonatomic, readonly) BOOL isScaning;
@property (copy, nonatomic) ScanOutputs scanOutputs;//可選的實(shí)現(xiàn)掃描多個(gè)二維碼后的預(yù)測(cè)操作煮岁。比如自動(dòng)選擇某個(gè)二維碼
- (void)startScan;
- (void)stopScan;
//+ (NSArray <NSDictionary *> *)scanWithImage:(UIImage*)image; //暫未實(shí)現(xiàn)
- (instancetype)initWithScanResultBlock:(ScanResultBlock)block;//二維碼點(diǎn)選操作
@end
.m
.m:
#import "XYQRScanViewController.h"
#import "UIColor+DynamicColor.h"
#import "HDXYScanImageSelectController.h"
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define kDevice_Is_iPhoneX (SCREEN_WIDTH >= 375.f && SCREEN_HEIGHT >= 812.f)
#define kSafeArea_Top (kDevice_Is_iPhoneX? 44: 20 )
@interface XYQRScanViewController ()<AVCaptureMetadataOutputObjectsDelegate, UIImagePickerControllerDelegate,AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic, strong) UILabel *promptLabel;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIView *bottomView;
@property (strong, nonatomic) UIView *myScanBGView;
@property (strong, nonatomic) UIImageView *scanRectView, *lineView;
@property (strong, nonatomic) UILabel *tipLabel;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (strong, nonatomic) CIDetector *detector;
@property (strong, nonatomic) UIButton *lightButton;
@property (strong,nonatomic)UIButton *photoButton;
@property (strong,nonatomic)UIButton *codeButton;
@property (strong, nonatomic) UIView *topBg;
@property (nonatomic,assign)CGRect scanRect;
@property (nonatomic,strong)UIView *bottomContentView;
@property (nonatomic,strong)UILabel *cricleLabel;
//@property (nonatomic,strong)MLMSegmentHead *segemetHead;
@property (nonatomic,strong)UIButton *popButton;
@property (assign, nonatomic, readwrite) BOOL isScaning;
@property (nonatomic, copy) void(^scanBlock)(NSString *scanStr);//掃碼回調(diào)
@end
@implementation XYQRScanViewController
- (instancetype)initWithScanResultBlock:(ScanResultBlock)block
{
self = [super init];
if (self) {
_scanBlock = block;
}
return self;
}
- (CIDetector *)detector{
if (!_detector) {
_detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
}
return _detector;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIColor *color = [UIColor colorWithDarkModeColor:BlackColor normalColor:HexF7F8FA];
self.view.backgroundColor = color;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[nc addObserver:self
selector:@selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
[self configUI];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = NO;
[self startScan];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
}
- (void)setupNavigationBar {
self.navigationController.navigationBar.translucent = YES;
[self.navigationController.navigationBar setBackgroundImage:[UIImage createImageWithColor:[UIColor clearColor]] forBarMetrics:UIBarMetricsDefault];
NSDictionary *textAttributes = @{
NSFontAttributeName: [UIFont boldSystemFontOfSize:18],
NSForegroundColorAttributeName:WhiteColor
};
[self.navigationController.navigationBar setTitleTextAttributes:textAttributes];
self.navigationItem.title = @"掃碼";
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 40, 40);
[backButton setImage:[UIImage imageNamed:@"nav_back_w"] forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(scanBack) forControlEvents:UIControlEventTouchUpInside];
backButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
rightButton.frame = CGRectMake(0, 0, 40, 40);
[rightButton setTitle:@"相冊(cè)" forState:UIControlStateNormal];
[rightButton setTitleColor:WhiteColor forState:UIControlStateNormal];
rightButton.titleLabel.font = FontRegular(16);
rightButton.alpha = 0.8;
[rightButton addTarget:self action:@selector(rightBarButtonItenAction) forControlEvents:UIControlEventTouchUpInside];
rightButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
}
-(void)configUI{
[self setupNavigationBar];
_isScaning = YES;
[self.view.layer addSublayer:self.videoPreviewLayer];
[self.view addSubview:self.titleLabel];
[self.view addSubview:self.promptLabel];
[self.view addSubview:self.myScanBGView];
[self.view addSubview:self.lineView];
[self scanLineStartAction];
}
- (void)scanLineStartAction{
[self scanLineStopAction];
CAAnimationGroup *group = [CAAnimationGroup animation];
CABasicAnimation *scanAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
scanAnimation.fromValue = @(80);
scanAnimation.toValue = @(SCREEN_HEIGHT-160-95);
scanAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.fromValue = @(1);
opacityAnimation.toValue = @(0);
opacityAnimation.repeatCount = CGFLOAT_MAX;
opacityAnimation.duration = 0.5;
opacityAnimation.beginTime = 2;
group.animations = @[scanAnimation,opacityAnimation];
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
group.duration = 2.5;
group.repeatCount = CGFLOAT_MAX;
[self.lineView.layer addAnimation:group forKey:@"basic"];
}
-(void)scanLineStopAction{
[self.lineView.layer removeAllAnimations];
}
-(void)scanBack{
if (self.navigationController) {
[self.navigationController popViewControllerAnimated:YES];
}
}
- (void)rightBarButtonItenAction {
WeakSelf(ws);
UIImagePickerController *picker = [UIImagePickerController new];
picker.delegate = (id)self;
picker.allowsEditing = NO;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.modalPresentationStyle = UIModalPresentationFullScreen;
[ws.navigationController presentViewController:picker animated:YES completion:nil];
}
-(void)dealloc {
[self.videoPreviewLayer removeFromSuperlayer];
self.videoPreviewLayer = nil;
[self scanLineStopAction];
[[NSNotificationCenter defaultCenter] removeObserver:self];
NSLog(@"%s",__func__);
}
#pragma mark -----public
- (void)playSoundName:(NSString *)name {
/// 靜態(tài)庫(kù) path 的獲取
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:nil];
if (!path) {
/// 動(dòng)態(tài)庫(kù) path 的獲取
path = [[NSBundle bundleForClass:[self class]] pathForResource:name ofType:nil];
}
NSURL *fileUrl = [NSURL fileURLWithPath:path];
SystemSoundID soundID = 0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, NULL, NULL);
AudioServicesPlaySystemSound(soundID);
}
- (void)startScan{
_isScaning = YES;
[self.videoPreviewLayer.session startRunning];
[self scanLineStartAction];
}
- (void)stopScan{
_isScaning = NO;
[self.videoPreviewLayer.session stopRunning];
[self scanLineStopAction];
}
-(void)openFlash:(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.torchMode = AVCaptureTorchModeOn;
} else {
device.torchMode = AVCaptureTorchModeOff;
}
[device unlockForConfiguration];
}
}
}
#pragma mark -----Notification
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self startScan];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[self stopScan];
}
#pragma mark ------imagepickDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info
{
WeakSelf(weakSelf);
[picker dismissViewControllerAnimated:YES completion:^{
[weakSelf handleImageInfo:info];
}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
[self startScan];
}
+(UIViewController *)showSelectControllerWithImage:(UIImage *)image dataArray:(NSArray *)array block:(ScanResultBlock)block
{
HDXYScanImageSelectController *controller = [HDXYScanImageSelectController new];
controller.image =image;
controller.tagArray = array;
controller.scanBlock = block;
return controller;
}
#pragma mark 圖片識(shí)別
- (void)handleImageInfo:(NSDictionary *)info{
[self startScan];
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
if (!image){
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
__block NSString *resultStr = nil;
__block BOOL haveCode = NO;
//圖片識(shí)別二維碼
NSArray *features = [self.detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
//判斷是否識(shí)別出二維碼
[features enumerateObjectsUsingBlock:^(CIQRCodeFeature *obj, NSUInteger idx, BOOL *stop) {
if (obj.messageString.length > 0) {
resultStr = obj.messageString;
NSLog(@"%@",resultStr);
haveCode = resultStr.length>0?YES:NO;
*stop = YES;
}
}];
[self stopScan];
NSMutableArray *muchArray = [NSMutableArray new];
if (haveCode) {
[features enumerateObjectsUsingBlock:^(CIQRCodeFeature *obj, NSUInteger idx, BOOL *stop) {
NSMutableDictionary *dic = [NSMutableDictionary new];
CGRect frame =obj.bounds;
NSString *frameStr = NSStringFromCGRect(frame);
[dic setObject:frameStr forKey:@"frame"];
NSString *code = obj.messageString;
[dic setObject:code forKey:@"code"];
[muchArray addObject:dic];
}];
}
if (self.scanOutputs) {
self.scanOutputs(muchArray);
return;
}
WeakSelf(weakSelf);
[self.navigationController pushViewController:[XYQRScanViewController showSelectControllerWithImage:image dataArray:muchArray block:^(NSString *result) {
if (result && result.length>0) {
if (weakSelf.scanBlock) {
[weakSelf.navigationController popViewControllerAnimated:NO];
weakSelf.scanBlock(result);
}
}
}] animated:NO];
return;
}
#pragma mark ------AVCaptureVideoDataOutputSampleBufferDelegate
//弱光識(shí)別
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
static BOOL isStop = false;
if (isStop) return;
isStop = true;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//0.5秒一次弱光監(jiān)聽
isStop = false;
});
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
CFRelease(metadataDict);
NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
if (brightnessValue < 0 && !self.lightButton.selected && self.lightButton.isHidden) {
self.lightButton.hidden = NO;
}
if (brightnessValue > 0 && !self.lightButton.selected && !self.lightButton.isHidden) {
self.lightButton.hidden = YES;
}
}
#pragma mark ------AVCaptureMetadataOutputObjectsDelegate讥蔽,掃描結(jié)果輸出流代理
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
//判斷是否有數(shù)據(jù),是否是二維碼數(shù)據(jù)
NSMutableArray *muchArray = [NSMutableArray new];
if (metadataObjects.count > 0) {
[metadataObjects enumerateObjectsUsingBlock:^(AVMetadataMachineReadableCodeObject *obj, NSUInteger idx, BOOL *stop) {
if ([obj.type isEqualToString:AVMetadataObjectTypeQRCode]) {
[muchArray addObject:obj];
}
}];
if (muchArray.count>0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self analyseResultAry:muchArray];
});
}
}
}
- (void)analyseResultAry:(NSArray *)resultArray{
if (!_isScaning) {
return;
}
[self stopScan];
[self playSoundName:@"SGQRCode.bundle/sound.caf"];
NSMutableArray *muchArray = [NSMutableArray new];
[resultArray enumerateObjectsUsingBlock:^(AVMetadataMachineReadableCodeObject *result, NSUInteger idx, BOOL *stop) {
NSMutableDictionary *dic = [NSMutableDictionary new];
NSString *code = result.stringValue;
[dic setObject:code forKey:@"code"];
CGRect frame = [self makeFrameWithCodeObject: result];
NSString *frameStr = NSStringFromCGRect(frame);
[dic setObject:frameStr forKey:@"frame"];
[muchArray addObject:dic];
}];
if (muchArray.count>=1) {
UIImage *image;
WeakSelf(weakSelf);
if (self.scanOutputs) {
self.scanOutputs(muchArray);
return;
}
UIViewController *viewController = [XYQRScanViewController showSelectControllerWithImage:image dataArray:muchArray block:^(NSString *result) {
weakSelf.popButton.hidden = NO;
weakSelf.lineView.hidden = NO;
if (weakSelf.scanBlock) {
if (result) {
[weakSelf.navigationController popViewControllerAnimated:YES];
weakSelf.scanBlock(result);
}else{
[weakSelf startScan];
}
}
}];
viewController.modalPresentationStyle =UIModalPresentationOverFullScreen;
[self.navigationController presentViewController:viewController animated:NO completion:nil];
self.popButton.hidden = YES;
self.lineView.hidden = YES;
return;
}
[self startScan];
}
/*
AVMetadataMachineReadableCodeObject人乓,輸出的點(diǎn)位坐標(biāo)是其在原始數(shù)據(jù)流上的坐標(biāo)勤篮,與屏幕視圖坐標(biāo)不一樣,(坐標(biāo)系色罚,值都會(huì)有差別)
將坐標(biāo)值轉(zhuǎn)為屏幕顯示的圖像視圖(self.videoPreviewLayer)上的坐標(biāo)值
*/
-(CGRect)makeFrameWithCodeObject:(AVMetadataMachineReadableCodeObject *)objc
{
//將二維碼坐標(biāo)轉(zhuǎn)化為掃碼控件輸出視圖上的坐標(biāo)
CGSize isize = CGSizeMake(720.0, 1280.0); // 尺寸可以考慮不要寫死,當(dāng)前設(shè)置的是captureSession.sessionPreset = AVCaptureSessionPreset1280x720;
// CGSize isize = self.view.frame.size; //掃碼控件的輸出尺寸,
float Wout = 0.00;
float Hout = 0.00;
BOOL wMore = YES;
/*取分辨率與輸出的layer尺寸差账劲,
此處以AVLayerVideoGravityResizeAspectFill填充方式為例戳护,判斷掃描的范圍更寬還是更長(zhǎng),并計(jì)算出超出部分的尺寸瀑焦,后續(xù)計(jì)算減去這部分腌且。
如果是其它填充方式,計(jì)算方式不一樣(比如AVLayerVideoGravityResizeAspect榛瓮,則計(jì)算計(jì)算留白的尺寸铺董,并后續(xù)補(bǔ)足這部分)
*/
if (isize.width/isize.height > self.videoPreviewLayer.bounds.size.width/self.videoPreviewLayer.bounds.size.height) {
//當(dāng)更寬時(shí),計(jì)算掃描的坐標(biāo)x為0 的點(diǎn)比輸出視圖的0點(diǎn)差多少(輸出視圖為全屏?xí)r,即屏幕外有多少)
wMore = YES;
Wout = (isize.width/isize.height)* self.videoPreviewLayer.bounds.size.height;
Wout = Wout - self.videoPreviewLayer.bounds.size.width;
Wout = Wout/2;
}else{
// 當(dāng)更長(zhǎng)時(shí)精续,計(jì)算y軸超出多少坝锰。
wMore = NO;
Hout = (isize.height/isize.width)* self.videoPreviewLayer.bounds.size.width;
Hout = Hout - self.videoPreviewLayer.bounds.size.height;
Hout = Hout/2;
}
CGPoint point1 = CGPointZero;
CGPoint point2 = CGPointZero;
CGPoint point3 = CGPointZero;
CGPoint point4 = CGPointZero;
/*
源坐標(biāo)系下frame和角點(diǎn),都是比例值重付,即源視頻流尺寸下的百分比值顷级。
例子:frame :(x = 0.26720550656318665, y = 0.0014114481164142489), size = (width = 0.16406852006912231, height = 0.29584407806396484))
objc.corners:{0.26823519751360592, 0.29203594744002659}
{0.4312740177700658, 0.29725551905635411}
{0.4294213439632073, 0.012761536345436197}
{0.26720551457151021, 0.0014114481640513654}
*/
CGRect frame = objc.bounds;//在源坐標(biāo)系的frame,
NSArray *array = objc.corners;//源坐標(biāo)系下二維碼的角點(diǎn)
CGPoint P = frame.origin;
CGSize S = frame.size;
//獲取點(diǎn)
for (int n = 0; n< array.count; n++) {
CGPoint point = CGPointZero;
CFDictionaryRef dict = (__bridge CFDictionaryRef)(array[n]);
CGPointMakeWithDictionaryRepresentation(dict, &point);
NSLog(@"二維碼角點(diǎn)%@",NSStringFromCGPoint(point));
//交換xy軸
point.x = point.y + point.x;
point.y = point.x - point.y;
point.x = point.x - point.y;
//x軸反轉(zhuǎn)
point.x = (1-point.x);
//point乘以比列确垫。減去尺寸差弓颈,
if (wMore) {
point.x = (point.x * (isize.width/isize.height)* self.videoPreviewLayer.bounds.size.height) - Wout;
point.y = self.videoPreviewLayer.bounds.size.height *(point.y);
}else{
point.x = self.videoPreviewLayer.bounds.size.width *(point.x);
point.y = (point.y) * (isize.height/isize.width)* self.videoPreviewLayer.bounds.size.width - Hout;
}
if (n == 0) {
point1 = point;
}
if (n == 1) {
point2 = point;
}
if (n == 2) {
point3 = point;
}
if (n == 3) {
point4 = point;
}
}
//通過獲取最小和最大的X,Y值删掀,二維碼在視圖上的frame(前面得到的點(diǎn)不一定是正方形的二維碼翔冀,也可能是菱形的或者有一定旋轉(zhuǎn)角度的)
float minX = point1.x;
minX = minX>point2.x?point2.x:minX;
minX = minX>point3.x?point3.x:minX;
minX = minX>point4.x?point4.x:minX;
float minY = point1.y;
minY = minY>point2.y?point2.y:minY;
minY = minY>point3.y?point3.y:minY;
minY = minY>point4.y?point4.y:minY;
P.x = minX;
P.y = minY;
float maxX = point1.x;
maxX = maxX<point2.x?point2.x:maxX;
maxX = maxX<point3.x?point3.x:maxX;
maxX = maxX<point4.x?point4.x:maxX;
float maxY = point1.y;
maxY = maxY<point2.y?point2.y:maxY;
maxY = maxY<point3.y?point3.y:maxY;
maxY = maxY<point4.y?point4.y:maxY;
S.width = maxX - minX;
S.height = maxY - minY;
//y軸坐標(biāo)方向調(diào)整
CGRect QRFrame = CGRectMake(P.x , P.y , S.width, S.width);
return QRFrame;
}
#pragma mark 懶加載
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.backgroundColor = [UIColor clearColor];
CGFloat promptLabelX = 0;
CGFloat promptLabelY = 0.12 * SCREEN_HEIGHT;
CGFloat promptLabelW = SCREEN_WIDTH;
CGFloat promptLabelH = 25;
_titleLabel.frame = CGRectMake(promptLabelX, promptLabelY, promptLabelW, promptLabelH);
_titleLabel.textAlignment = NSTextAlignmentCenter;
_titleLabel.font = FontRegular(16);
_titleLabel.textColor = WhiteColor;
_titleLabel.alpha = 0.8;
_titleLabel.text = @"掃描二維碼";
}
return _titleLabel;
}
- (UIView *)bottomView {
if (!_bottomView) {
_bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 0)];
_bottomView.backgroundColor = [BlackColor colorWithAlphaComponent:0.6];
}
return _bottomView;
}
-(UIImageView *)lineView{
if (!_lineView){
/// 靜態(tài)庫(kù) url 的獲取, 掃描線暫時(shí)用的原第三方庫(kù)的圖片,
NSURL *url = [[NSBundle mainBundle] URLForResource:@"SGQRCode" withExtension:@"bundle"];
if (!url) {
/// 動(dòng)態(tài)庫(kù) url 的獲取
url = [[NSBundle bundleForClass:[self class]] URLForResource:@"SGQRCode" withExtension:@"bundle"];
}
NSBundle *bundle = [NSBundle bundleWithURL:url];
UIImage *image = [UIImage imageNamed:@"QRCodeScanLine" inBundle:bundle compatibleWithTraitCollection:nil];
if (!image) {
image = [UIImage imageNamed:@"QRCodeScanLine"];
}
// UIImage *lineImage = [UIImage imageNamed:@"QRCodeScanLine@2x.png"];
CGFloat lineHeight = 30;
CGFloat lineWidth = CGRectGetWidth(self.view.frame);
_lineView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 40, lineWidth, lineHeight)];
_lineView.contentMode = UIViewContentModeScaleToFill;
_lineView.image = image;
}
return _lineView;
}
-(AVCaptureVideoPreviewLayer *)videoPreviewLayer{
if (!_videoPreviewLayer) {
NSError *error;
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //相機(jī)的硬件接口
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error]; // 用于流的捕獲,輸入流
if (!input) {
NSLog(@"%@", error.localizedDescription);
[self.navigationController popViewControllerAnimated:YES];
return nil;
}else{
//設(shè)置視頻會(huì)話(時(shí)域)流
AVCaptureSession *captureSession = [AVCaptureSession new];
[captureSession addInput:input]; //設(shè)置輸入流
captureSession.sessionPreset = AVCaptureSessionPreset1280x720; //輸出的分辨率
//創(chuàng)建流輸出
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatch_queue_create("ease_capture_queue",NULL)];//設(shè)置輸出代理披泪,及處理線程(輸出類型為上面設(shè)置的類型纤子,比如二維碼或人臉數(shù)據(jù)或者別的等等)
[captureSession addOutput:captureMetadataOutput];//添加流輸出到session
//設(shè)置輸出類型:AVMetadataObjectTypeQRCode,//其它功能比如人臉掃描等可以自行研究
if (![captureMetadataOutput.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]) {
NSLog(NSLocalizedString(@"攝像頭不支持掃描二維碼付呕!", nil));
[self.navigationController popViewControllerAnimated:YES];
}else{
[captureMetadataOutput setMetadataObjectTypes:captureMetadataOutput.availableMetadataObjectTypes];
}
captureMetadataOutput.rectOfInterest = CGRectMake(0,0,1,1);//設(shè)置掃描區(qū)域计福。。默認(rèn)是手機(jī)頭向左的橫屏坐標(biāo)系(逆時(shí)針旋轉(zhuǎn)90度)徽职,左上角為(0象颖,0)點(diǎn).坐標(biāo)系↓→
// 弱光識(shí)別監(jiān)聽
AVCaptureVideoDataOutput *buffer = [[AVCaptureVideoDataOutput alloc] init];
[buffer setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
if ([captureSession canAddOutput:buffer]){
[captureSession addOutput:buffer];
}
//將捕獲的數(shù)據(jù)流展現(xiàn)出來
_videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; //等比例填充,超出部分會(huì)被剪裁(這也就是為什么有些掃碼屏幕內(nèi)只顯示了一半也能完成掃描姆钉。其實(shí)攝像頭已經(jīng)捕獲了)(AVLayerVideoGravityResizeAspect全部顯示说订,少的部分有留白)
[_videoPreviewLayer setFrame:self.view.bounds];
// //以下是修改掃描區(qū)域?yàn)槠聊粌?nèi)的方案,修改參數(shù)可以指定范圍內(nèi)掃描
// CGSize isize = CGSizeMake(720.0, 1280.0); //當(dāng)前設(shè)置的是captureSession.sessionPreset = AVCaptureSessionPreset1280x720;
// float Wout = 0.00;
// float Hout = 0.00;
// BOOL wMore = YES;
// //取分辨率與輸出的layer尺寸差潮瓶,首先判斷目掃描的范圍更寬還是更長(zhǎng)陶冷,
// if (isize.width/isize.height > self.view.bounds.size.width/self.view.bounds.size.height) {
// //當(dāng)更寬時(shí),計(jì)算掃描的坐標(biāo)x為0 的點(diǎn)比輸出視圖的0點(diǎn)差多少(輸出視圖為全屏?xí)r毯辅,即屏幕外有多少)
// wMore = YES;
// Wout = (isize.width/isize.height)* self.videoPreviewLayer.bounds.size.height;
// Wout = Wout - self.videoPreviewLayer.bounds.size.width;
// Wout = Wout/2;
// }else{
// // 當(dāng)更長(zhǎng)時(shí)埂伦,計(jì)算y軸超出多少。
// wMore = NO;
// Hout = (isize.height/isize.width)* self.videoPreviewLayer.bounds.size.width;
// Hout = Hout - self.videoPreviewLayer.bounds.size.height;
// Hout = Hout/2;
// }
// if (wMore) {
// captureMetadataOutput.rectOfInterest = CGRectMake(0,Wout/720.0,1,(720.0-2*Wout)/720.0);
// }else{
// captureMetadataOutput.rectOfInterest = CGRectMake(Hout/1280.0,0,(1280.0-2*Hout)/1280.0,0);
// }
// captureMetadataOutput.rectOfInterest = CGRectMake(0,0,0.5,0.5);
}
}
return _videoPreviewLayer;
}
@end
展示點(diǎn)選按鈕
.h:
#import <UIKit/UIKit.h>
@interface HDXYScanImageSelectController : UIViewController
@property (nonatomic, copy) void(^scanBlock)(NSString *scanStr);//掃碼點(diǎn)選回調(diào)
/*
選擇圖片掃碼結(jié)果展示:傳入image思恐。
攝像頭掃碼結(jié)果展示:image不需要傳入沾谜,后面會(huì)自動(dòng)生成透明圖片尺寸與掃碼頁面視頻流的展示大小一致,如果掃碼頁面視頻流不是全圖則需要修改這部分邏輯
*/
@property(nonatomic,copy)UIImage *image;
@property(nonatomic,copy)NSArray *tagArray;
@end
.m:
#import "HDXYScanImageSelectController.h"
#define maxBtnSize 54
#define minBtnSize 18
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define kDevice_Is_iPhoneX (SCREEN_WIDTH >= 375.f && SCREEN_HEIGHT >= 812.f)
#define kSafeArea_Top (kDevice_Is_iPhoneX? 44: 20 )
#define kSafeArea_Bottom ((kDevice_Is_iPhoneX? 34: 0))
@interface HDXYScanImageSelectController ()
@property (nonatomic,strong)UIButton *popButton;
@property (nonatomic,strong)UILabel *downLable;
@property (nonatomic,strong)UIView *bigDarkView;
@property BOOL noImage;
@end
@implementation HDXYScanImageSelectController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.popButton];
[self.popButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(25);
make.top.equalTo(self.view).offset(12.5+(kDevice_Is_iPhoneX?44:20));
}];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated
{
self.view.backgroundColor = [UIColor blackColor];
self.navigationController.navigationBar.hidden = YES;
self.noImage = NO;
if (!self.image) {
self.noImage = YES;
self.image = [self createImageWithColor:[UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.5]];
self.view.backgroundColor = [UIColor clearColor];
}
UIImageView *imageView = [self buildImageView];
[self.view addSubview:imageView];
if (self.tagArray && self.tagArray.count>0) {
[self.tagArray enumerateObjectsUsingBlock:^(NSDictionary *dataDic, NSUInteger idx, BOOL *stop) {
UIButton *btn = [self buildBtnWithDic:dataDic andNumber:idx];
[imageView addSubview:btn];
}];
[self.view addSubview:self.downLable];
[self.downLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view.mas_centerX);
make.bottom.mas_offset(-40-kSafeArea_Bottom);
}];
[self.view bringSubviewToFront:self.popButton];
}else{
[self.view addSubview:self.bigDarkView];
[self.bigDarkView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.bottom.mas_equalTo(self.view);
}];
}
[self.view bringSubviewToFront:self.popButton];
[super viewWillAppear:animated];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//只有一個(gè)二維碼時(shí)胀莹,展示一下就自動(dòng)選擇
if (self.tagArray.count == 1) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSDictionary *dataDic = self.tagArray[0];
[self doingWithMessage:dataDic[@"code"]];
});
}
}
-(UIButton *)buildBtnWithDic:(NSDictionary *)dic andNumber:(NSInteger)number
{
CGSize startImageSize = [HDXYScanImageSelectController getSizeWithImage:self.image];
CGFloat fixelW = startImageSize.width;
CGFloat fixelH = startImageSize.height;
//計(jì)算UIimageView的尺寸基跑,
if (fixelH/fixelW > self.view.bounds.size.height/self.view.bounds.size.width) {
fixelW = (fixelW/fixelH) * self.view.bounds.size.height;
fixelH = self.view.bounds.size.height;
}else{
fixelH = (fixelH/fixelW) * self.view.bounds.size.width;
fixelW = self.view.bounds.size.width;
}
float scale = fixelW/startImageSize.width;
CGRect btnFrame = CGRectFromString(dic[@"frame"]);
//根據(jù)圖片方向調(diào)整frame
if (!self.noImage) {
btnFrame = [HDXYScanImageSelectController exChangeFrame:btnFrame withImage:self.image];
}
//坐標(biāo)等比縮放
btnFrame = CGRectMake(btnFrame.origin.x*scale, btnFrame.origin.y *scale, btnFrame.size.width *scale, btnFrame.size.height *scale);
//按鈕初步大小調(diào)整
btnFrame = CGRectMake(btnFrame.origin.x + btnFrame.size.width/4,btnFrame.origin.y + btnFrame.size.height/4, btnFrame.size.width/2, btnFrame.size.height/2);
if (btnFrame.size.width != btnFrame.size.height) {
float w = btnFrame.size.width;
float h = btnFrame.size.height;
btnFrame = CGRectMake(btnFrame.origin.x, btnFrame.origin.y + (h-w)/2, w, w);
}
if (btnFrame.size.width > maxBtnSize) {
float w = btnFrame.size.width;
float h = btnFrame.size.height;
btnFrame = CGRectMake(btnFrame.origin.x + (w-maxBtnSize)/2, btnFrame.origin.y + (h-maxBtnSize)/2, maxBtnSize, maxBtnSize);
}
if (btnFrame.size.width < minBtnSize) {
float w = btnFrame.size.width;
float h = btnFrame.size.height;
btnFrame = CGRectMake(btnFrame.origin.x + (w-minBtnSize)/2, btnFrame.origin.y + (h-minBtnSize)/2, minBtnSize, minBtnSize);
}
btnFrame.size.width = btnFrame.size.height;
UIButton *btn = [[UIButton alloc]init];
btn.frame = btnFrame;
[btn setBackgroundImage:[UIImage imageNamed:@"scanMany"] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor yellowColor];
btn.alpha = 0.99;
btn.tag = number;
btn.clipsToBounds = YES;
[btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
[btn.layer addAnimation:[self opacityForever_Animation:0.7] forKey:nil];
return btn;
}
-(void)clickBtn:(UIButton *)btn
{
NSInteger number = btn.tag;
NSString *messageStr = self.tagArray[number][@"code"];
[self doingWithMessage:messageStr];
}
-(void)clickBigBackView:(id)sender
{
[self doingWithMessage:nil];
}
-(void)doingWithMessage:(NSString *)msg
{
if (self.navigationController) {
[self.navigationController popViewControllerAnimated:YES];
if (self.scanBlock) {
self.scanBlock(msg);
}
}else{
[self dismissViewControllerAnimated:NO completion:^{
if (self.scanBlock) {
self.scanBlock(msg);
}
}];
}
}
#pragma mark === 永久閃爍的動(dòng)畫 ======
-(CABasicAnimation *)opacityForever_Animation:(float)time
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = [NSNumber numberWithFloat:0.99f];
animation.toValue = [NSNumber numberWithFloat:0.3f];
animation.autoreverses = YES;
animation.duration = time;
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];///沒有的話是均勻的動(dòng)畫。
return animation;
}
+(CGSize)getSizeWithImage:(UIImage *)image
{
CGFloat fixelW;
CGFloat fixelH;
fixelW = CGImageGetWidth(image.CGImage);
fixelH = CGImageGetHeight(image.CGImage);
if (image.imageOrientation == UIImageOrientationLeft ||
image.imageOrientation == UIImageOrientationRight ||
image.imageOrientation == UIImageOrientationLeftMirrored ||
image.imageOrientation == UIImageOrientationRightMirrored) {
fixelW = CGImageGetHeight(image.CGImage);
fixelH = CGImageGetWidth(image.CGImage);
}
return CGSizeMake(fixelW, fixelH);
}
//根據(jù)圖片方向調(diào)整二維碼坐標(biāo),圖片方向根據(jù)拍攝時(shí)手機(jī)方向而不同
+(CGRect)exChangeFrame:(CGRect)frame withImage:(UIImage *)image
{
CGFloat fixelW = CGImageGetWidth(image.CGImage);
CGFloat fixelH = CGImageGetHeight(image.CGImage);
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat w = frame.size.width;
CGFloat h = frame.size.height;
if (image.imageOrientation == UIImageOrientationUp){
frame.origin.y = fixelH-y-h;
}else if (image.imageOrientation == UIImageOrientationLeft){
//方向逆時(shí)針旋轉(zhuǎn)90°拍攝,已實(shí)現(xiàn)
frame.origin.x = fixelH-y-h;
frame.origin.y = fixelW-x-w;
}else if (image.imageOrientation == UIImageOrientationRight){
//順時(shí)針旋轉(zhuǎn)90度拍攝描焰,已實(shí)現(xiàn)
frame.origin.x = y;
frame.origin.y = x;
}else if (image.imageOrientation == UIImageOrientationDown){
//旋轉(zhuǎn)180度拍攝的
frame.origin.x = fixelW-x-w;
frame.origin.y = y;
}else if (image.imageOrientation == UIImageOrientationUpMirrored){
//左右鏡像媳否,已實(shí)現(xiàn)未驗(yàn)證
frame.origin.x = fixelW -x-w;
frame.origin.y = fixelH-y-h;
}else if (image.imageOrientation == UIImageOrientationDownMirrored){
//翻轉(zhuǎn)180度后鏡像,已實(shí)現(xiàn)未驗(yàn)證
frame.origin.y = y;
frame.origin.x = x;
}else if (image.imageOrientation == UIImageOrientationRightMirrored){
//表示圖片被順時(shí)針翻轉(zhuǎn)90°后的鏡面圖像,已實(shí)現(xiàn)未驗(yàn)證
frame.origin.x = fixelH -y-h;
frame.origin.y = x;
}else if (image.imageOrientation == UIImageOrientationLeftMirrored){
//坐標(biāo)系逆時(shí)針旋轉(zhuǎn)90°并鏡像,已實(shí)現(xiàn)未驗(yàn)證
frame.origin.x = y;
frame.origin.y = fixelW-x-w;
}
return frame;
}
-(UIImageView *)buildImageView
{
CGFloat fixelW = [HDXYScanImageSelectController getSizeWithImage:self.image].width;
CGFloat fixelH = [HDXYScanImageSelectController getSizeWithImage:self.image].height;
if (fixelH/fixelW > self.view.bounds.size.height/self.view.bounds.size.width) {
fixelW = (fixelW/fixelH) * self.view.bounds.size.height;
fixelH = self.view.bounds.size.height;
}else{
fixelH = (fixelH/fixelW) * self.view.bounds.size.width;
fixelW = self.view.bounds.size.width;
}
UIImageView *imageView = [[UIImageView alloc]initWithImage:self.image];
imageView.bounds = CGRectMake(0, 0, fixelW, fixelH);
imageView.center = self.view.center;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.userInteractionEnabled = YES;
return imageView;
}
-(UIButton *)popButton{
if (!_popButton) {
_popButton = [[UIButton alloc]init];
// [_popButton setImage:[UIImage imageNamed:@"scan_closed_icon"] forState:UIControlStateNormal];
[_popButton setTitle:@"取消" forState:UIControlStateNormal];
[_popButton addTarget:self action:@selector(clickBigBackView:) forControlEvents:UIControlEventTouchUpInside];
}
return _popButton;
}
-(UILabel *)downLable
{
if (!_downLable) {
_downLable = [UILabel new];
_downLable.text = @"輕觸小藍(lán)點(diǎn)篱竭,打開頁面";
[_downLable setTextColor:[UIColor whiteColor]];
[_downLable setBackgroundColor:[UIColor clearColor]];
_downLable.textAlignment = NSTextAlignmentCenter;
}
return _downLable;
}
//顏色生成image
-(UIImage*) createImageWithColor:(UIColor*) color
{
CGRect rect=CGRectMake(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}
-(UIView *)bigDarkView
{
if (!_bigDarkView) {
_bigDarkView = [UIView new];
_bigDarkView.backgroundColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:0.5];
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickBigBackView:)];
[tapGesture setNumberOfTapsRequired:1];
[_bigDarkView addGestureRecognizer:tapGesture];
UILabel *oneLabel = [UILabel new];
oneLabel.text = @"未發(fā)現(xiàn)二維碼";
oneLabel.textColor = [UIColor whiteColor];
oneLabel.font = [UIFont fontWithName:@"FontWeightStyleRegular" size:17.0];
oneLabel.textAlignment = NSTextAlignmentCenter;
[_bigDarkView addSubview:oneLabel];
[oneLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(_bigDarkView);
make.height.mas_offset(20);
make.centerY.mas_equalTo(_bigDarkView.mas_centerY).mas_offset(-20);
}];
UILabel *twoLabel = [UILabel new];
twoLabel.text = @"輕觸屏幕繼續(xù)掃描";
twoLabel.textColor = [UIColor whiteColor];
twoLabel.font = [UIFont fontWithName:@"FontWeightStyleRegular" size:14.0];;
twoLabel.textAlignment = NSTextAlignmentCenter;
[_bigDarkView addSubview:twoLabel];
[twoLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(_bigDarkView);
make.height.mas_offset(20);
make.centerY.mas_equalTo(_bigDarkView.mas_centerY);
}];
}
return _bigDarkView;
}
@end