最近在做扫描二维码相关功能,网上关于这方面的介绍比较少,就稍微总结了一下,希望对大家有所帮助;
1.使用系统的AVFoundation做的二维码扫描器(iOS7以后),这方面的代码还是比较多的,以下是借鉴的代码。具体代码,参照:http://www.jianshu.com/p/6b7d54b3f88b
-(void)setupCamera {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗时的操作
// Device
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// Input
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
// Output
_output = [[AVCaptureMetadataOutput alloc]init];
// [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[ _output setRectOfInterest : CGRectMake ((60+64)/SCREEN_HEIGHT ,40/SCREEN_WIDTH , SCAN_HEIGHT/SCREEN_HEIGHT , SCAN_HEIGHT/SCREEN_WIDTH )];//限制扫描区域
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 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.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
// Preview
_preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
_preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
// _preview.frame =CGRectMake(20,110,280,280);
_preview.frame = self.view.bounds;
[self.view.layer insertSublayer:self.preview atIndex:0];
// Start
[_session startRunning];
});
});
}
注:关于扫描范围,可参照http://www.2cto.com/kf/201411/356046.html,该作者有关于这部分的详细解释。
2.添加黑色透明背景,中间透明区域,用于扫描,主要思想是添加一个黑色半透明view,使用CGContextClearRect方法,将扫描范围的正方形区域擦除。相关代码如下:
-(void) drawViewForScan {
ScanView* bgView = [[ScanView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
[self.view addSubview:bgView ];
//扫描区域
UIView* scanView = [[UIView alloc] initWithFrame:CGRectMake (40 , 60 + 64 ,SCAN_HEIGHT, SCAN_HEIGHT )];
scanView.backgroundColor = [UIColor clearColor];
[scanView.layer setMasksToBounds:YES];
[scanView.layer setBorderWidth:0.5];
scanView.layer.borderColor = [UIColor whiteColor].CGColor;
[self.view addSubview:scanView];
float width = 8.0f;
float height = 2.0f;
//左上角边框样式
UIView* LeftTopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width+height, height)];
LeftTopView.backgroundColor = [UIColor greenColor];
[scanView addSubview:LeftTopView];
UIView* LeftTopView2 = [[UIView alloc] initWithFrame:CGRectMake(0, height, height, width)];
LeftTopView2.backgroundColor = [UIColor greenColor];
[scanView addSubview:LeftTopView2];
//右上角边框样式
UIView* RightTopView = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-width-height, 0, width+height, height)];
RightTopView.backgroundColor = [UIColor greenColor];
[scanView addSubview:RightTopView];
UIView* RightTopView2 = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-height, height, height, width)];
RightTopView2.backgroundColor = [UIColor greenColor];
[scanView addSubview:RightTopView2];
//左下角边框样式
UIView* LeftLowView = [[UIView alloc] initWithFrame:CGRectMake(0, SCAN_HEIGHT-width-height, height, width)];
LeftLowView.backgroundColor = [UIColor greenColor];
[scanView addSubview:LeftLowView];
UIView* LeftLowView2 = [[UIView alloc] initWithFrame:CGRectMake(0, SCAN_HEIGHT-height, height+width, height)];
LeftLowView2.backgroundColor = [UIColor greenColor];
[scanView addSubview:LeftLowView2];
//右下角边框样式
UIView* RightLowView = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-height, SCAN_HEIGHT-width-height, height, width)];
RightLowView.backgroundColor = [UIColor greenColor];
[scanView addSubview:RightLowView];
UIView* RightLowView2 = [[UIView alloc] initWithFrame:CGRectMake(SCAN_HEIGHT-height-width, SCAN_HEIGHT-height, width+height, height)];
RightLowView2.backgroundColor = [UIColor greenColor];
[scanView addSubview:RightLowView2];
_line = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"line.png"]];
_line.frame = CGRectMake(0, 0, SCAN_HEIGHT, 2);
[scanView addSubview:_line];
}
CGContextClearRect方法在ScanView(黑色背景View,继承一个UIView就可以)的 - ( void )drawRect:(CGRect)rect方法里,相关代码如下:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect drawRect = CGRectMake (40 , 60 + 64 , SCREEN_WIDTH-80 , SCREEN_WIDTH-80 );
CGContextClearRect(context, drawRect); //clear the center rect of the layer
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) { //2
self.backgroundColor = [UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.5];
UILabel * labIntroudction= [[UILabel alloc] initWithFrame:CGRectMake(50, 60+64+SCAN_HEIGHT, SCAN_HEIGHT-10, 20)];
labIntroudction.backgroundColor = [UIColor clearColor];
//labIntroudction.numberOfLines=2;
labIntroudction.font = [UIFont systemFontOfSize:14.0f];
labIntroudction.textColor=[UIColor whiteColor];
labIntroudction.text=@"将二维码/条码放入框内,即可自动扫描";
[labIntroudction sizeToFit];
labIntroudction.center = CGPointMake(self.bounds.size.width/2,60+64+SCAN_HEIGHT+15);
[self addSubview:labIntroudction];
}
return self;
}
注:关于扫描区域的样式,即四个角都有绿色边角,也可以使用UIImageView,采用图片即可。
3.添加扫描动画效果,相关代码如下:
在- (void)viewDidLoad添加定时器初始化部分的代码,如下:
upOrdown = NO;
num =0;
timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
定时器动画代码:
-(void)animation1 {
if (upOrdown == NO) {
num++;
_line.frame = CGRectMake(0, num, SCAN_HEIGHT, 2);
if (num == SCAN_HEIGHT) {
num=0;
}
}
}
4.扫描成功事件响应,处理扫描结果。
#pragma mark AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
NSString *stringValue;
if ([metadataObjects count] >0) {
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
stringValue = metadataObject.stringValue;//扫描最终结果
}
[_session stopRunning];
[timer invalidate];
[self joinOrg:stringValue];//连接api方法
}
以上就是相关步骤以及代码,因为网上实在相关代码太少,尽管我写的不是太好,也希望帮到别人,由于经验不足,可能有的地方写的不到位,希望指正。