原計劃接下來更新UISearchController的文章,應朋友邀請,先更新一篇二維碼掃描的文章吧诫龙。
效果圖:
有點太靈敏了。蛹找。。
效果如上圖哨坪,內部就跳轉相應頁面庸疾,外部鏈接直接跳轉Safari,這里就不演示了当编,用的QRCodeViewController改的届慈,下面上代碼:
.h文件啥都沒有,就不貼了。
代碼:
#import "QRCodeViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "RRZFriendInfoController.h"
#import "RRZInfoDetailPageController.h"
#import "ScanBGView.h"
@interface QRCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (weak, nonatomic) IBOutlet UIView *viewPreview;
@property (weak, nonatomic) IBOutlet UILabel *lblStatus;
@property (strong, nonatomic) UILabel *tipLabel;
@property (strong, nonatomic) ScanBGView *myScanBGView;
@property (strong, nonatomic) UIImageView *scanRectView, *lineView;
@property (strong, nonatomic) UIView *boxView;
@property (nonatomic) BOOL isReading;
@property (strong, nonatomic) CALayer *scanLayer;
@property (strong,nonatomic) NSTimer *timer;
-(BOOL)startReading;
-(void)stopReading;
//捕捉會話
@property (nonatomic, strong) AVCaptureSession *captureSession;
//展示layer
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (nonatomic, strong) AVCaptureConnection * connection;
@end
@implementation QRCodeViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"二維碼掃描";
_captureSession = nil;
_isReading = NO;
[self startReading];
[self openUrl];
}
#pragma mark 設置焦距
- (void)setFocalLength:(CGFloat)lengthScale
{
[UIView animateWithDuration:0.5 animations:^{
[_videoPreviewLayer setAffineTransform:CGAffineTransformMakeScale(lengthScale, lengthScale)];
_connection.videoScaleAndCropFactor = lengthScale;
}];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.captureSession startRunning];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.captureSession stopRunning];
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
self.viewPreview.frame = self.view.bounds;
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
}
//實現startReading方法(這可就是重點咯)
- (BOOL)startReading {
NSError *error;
//1.初始化捕捉設備(AVCaptureDevice)金顿,類型為AVMediaTypeVideo
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//2.用captureDevice創(chuàng)建輸入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
}
//3.創(chuàng)建媒體數據輸出流
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
//4.實例化捕捉會話
_captureSession = [[AVCaptureSession alloc] init];
//4.1.將輸入流添加到會話
[_captureSession addInput:input];
//4.2.將媒體輸出流添加到會話中
[_captureSession addOutput:captureMetadataOutput];
//5.創(chuàng)建串行隊列臊泌,并加媒體輸出流添加到隊列當中
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
//5.1.設置代理
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
//5.2.設置輸出媒體數據類型為QRCode
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
//6.實例化預覽圖層
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
//7.設置預覽圖層填充方式
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//8.設置圖層的frame
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
//[_videoPreviewLayer setFrame:self.view.frame];
//9.將圖層添加到預覽view的圖層上
[_viewPreview.layer addSublayer:_videoPreviewLayer];
//10.設置掃描范圍
captureMetadataOutput.rectOfInterest = CGRectMake(0.2f, 0.2f, 0.8f, 0.8f);
_connection = [captureMetadataOutput connectionWithMediaType:AVMediaTypeVideo];
[self setFocalLength:2.0];//1倍正常,2x揍拆,3x渠概,4x依次放大
CGFloat width = SCREEN_WIDTH *2/3;
CGFloat padding = (SCREEN_WIDTH - width)/2;
CGFloat y = (SCREEN_HEIGHT - width) / 2;
CGRect scanRect = CGRectMake(padding, y, width, width);
if (!_myScanBGView) {
_myScanBGView = [[ScanBGView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
_myScanBGView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
_myScanBGView.scanRect = scanRect;
}
if (!_scanRectView) {
_scanRectView = [[UIImageView alloc] initWithFrame:scanRect];
_scanRectView.image = [[UIImage imageNamed:@"scan_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(25, 25, 25, 25)];
_scanRectView.clipsToBounds = YES;
}
if (!_tipLabel) {
_tipLabel = [UILabel new];
_tipLabel.textAlignment = NSTextAlignmentCenter;
_tipLabel.font = [UIFont boldSystemFontOfSize:16];
_tipLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.4];
_tipLabel.text = @"將二維碼放入框內,即可自動掃描";
}
if (!_lineView) {
UIImage *lineImage = [UIImage imageNamed:@"scan_line"];
CGFloat lineHeight = 2;
CGFloat lineWidth = CGRectGetWidth(_scanRectView.frame);
_lineView = [[UIImageView alloc] initWithFrame:CGRectMake(0, -lineHeight, lineWidth, lineHeight)];
_lineView.contentMode = UIViewContentModeScaleToFill;
_lineView.image = lineImage;
}
[self.view.layer addSublayer:_videoPreviewLayer];
[self.view addSubview:_myScanBGView];
[self.view addSubview:_scanRectView];
[self.view addSubview:_tipLabel];
[_tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.top.equalTo(_scanRectView.mas_bottom).offset(20);
make.height.mas_equalTo(30);
}];
[_scanRectView addSubview:_lineView]; //提示label
[self scanLineStartAction];
//11.開始掃描
[_captureSession startRunning];
return YES;
}
- (void)scanLineStartAction{
[self scanLineStopAction];
CABasicAnimation *scanAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
scanAnimation.fromValue = @(-CGRectGetHeight(_lineView.frame));
scanAnimation.toValue = @(CGRectGetHeight(_lineView.frame) + CGRectGetHeight(_scanRectView.frame));
scanAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
scanAnimation.repeatCount = CGFLOAT_MAX;
scanAnimation.duration = 2.0;
[self.lineView.layer addAnimation:scanAnimation forKey:@"basic"];
}
- (void)scanLineStopAction{
[self.lineView.layer removeAllAnimations];
}
//實現AVCaptureMetadataOutputObjectsDelegate協議方法
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
//判斷是否有數據
if (metadataObjects != nil && [metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
//判斷回傳的數據類型
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
[_lblStatus performSelectorOnMainThread:@selector(setText:) withObject:[metadataObj stringValue] waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
_isReading = NO;
}
}
// NSLog(@" 外 url is %@",_lblStatus.text);
}
//實現計時器方法moveScanLayer:(NSTimer *)timer
- (void)moveScanLayer:(NSTimer *)timer
{
CGRect frame = _scanLayer.frame;
if (_boxView.frame.size.height < _scanLayer.frame.origin.y+25) {
frame.origin.y = 0;
_scanLayer.frame = frame;
}else{
frame.origin.y += 25;
[UIView animateWithDuration:0.1 animations:^{
_scanLayer.frame = frame;
}];
}
}
- (void)openUrl {
NSLog(@"---------得到網址:%@-------",self.lblStatus.text);
NSString *resultAsString = self.lblStatus.text;
if (resultAsString.length > 0) {
//震動反饋
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
NSString *parametersType = [self jiexi:@"type" webaddress:resultAsString];
NSString *parametersId = [self jiexi:@"id" webaddress:resultAsString];
if ([parametersType isEqualToString:@"yryzcust"]) {
RRZFriendInfoController *friendInfoController = [[RRZFriendInfoController alloc]init];
friendInfoController.superiorType = 10;
friendInfoController.custId = parametersId;
[self.navigationController pushViewController:friendInfoController animated:YES];
}else if([parametersType isEqualToString:@"yryzinfo"]){
RRZInfoDetailPageController *detailPageController = [[RRZInfoDetailPageController alloc]init];
detailPageController.superiorType = 10;
detailPageController.infoID = parametersId;
[self.navigationController pushViewController:detailPageController animated:YES];
}else{
NSURL *url = [NSURL URLWithString:self.lblStatus.text];
if ([[UIApplication sharedApplication]canOpenURL:url]) {
[[UIApplication sharedApplication]openURL:url];
}else{
[MBProgressHUD showError:@"無法識別該二維碼" toView:self.view];
}
[self.navigationController popViewControllerAnimated:YES];
}
}
}
-(void)stopReading{
[_captureSession stopRunning];
_captureSession = nil;
[_scanLayer removeFromSuperlayer];
[_videoPreviewLayer removeFromSuperlayer];
[self openUrl];
}
#pragma mark - NSString
/**
* @author yichao, 16-04-21 11:04:39
*
* 從URL中獲取參數
*
* @param CS 參數名稱
* @param webaddress URL
*
* @return 參數
*/
-(NSString *) jiexi:(NSString *)CS webaddress:(NSString *)webaddress
{
NSError *error;
NSString *regTags=[[NSString alloc] initWithFormat:@"(^|&|\\?)+%@=+([^&]*)(&|$)",CS];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regTags
options:NSRegularExpressionCaseInsensitive
error:&error];
// 執(zhí)行匹配的過程
// NSString *webaddress=@"http://www.baidu.com/dd/adb.htm?adc=e12&xx=lkw&dalsjd=12";
NSArray *matches = [regex matchesInString:webaddress
options:0
range:NSMakeRange(0, [webaddress length])];
for (NSTextCheckingResult *match in matches) {
//NSRange matchRange = [match range];
//NSString *tagString = [webaddress substringWithRange:matchRange]; // 整個匹配串
// NSRange r1 = [match rangeAtIndex:1];
// if (!NSEqualRanges(r1, NSMakeRange(NSNotFound, 0))) { // 由時分組1可能沒有找到相應的匹配嫂拴,用這種辦法來判斷
// //NSString *tagName = [webaddress substringWithRange:r1]; // 分組1所對應的串
// return @"";
// }
NSString *tagValue = [webaddress substringWithRange:[match rangeAtIndex:2]]; // 分組2所對應的串
// NSLog(@"分組2所對應的串:%@\n",tagValue);
return tagValue;
}
return @"";
}
@end
all播揪,不清楚的歡迎留言。