您的位置:首页 > 移动开发 > IOS开发

iOS 原生态扫描二维码、条形码的功能。

2016-03-29 16:43 561 查看
1.导入AVFoundatin.framework。

2.新建一个viewController,命名为QRScanViewController,用于扫描的界面。

h文件如下,设置代理。

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@protocol QRScanDelegate <NSObject>

-(void)ReadScan:(NSString *)codetext;

@end

@interface QRScanViewController : UIViewController //<AVCaptureMetadataOutputObjectsDelegate>
{
id<QRScanDelegate> delegate;
}

@property (nonatomic,retain) id <QRScanDelegate> delegate;

@property (strong,nonatomic) UIView *boxView;

@property (strong,nonatomic) CALayer *scanLayer;

-(BOOL) startReading;

-(void) stopReading;

@property (nonatomic,strong) AVCaptureSession *captureSession;

@property (nonatomic,strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;

@property (strong, nonatomic) UIView *viewPreview;

@end


m文件内容如下

#import "QRScanViewController.h"

@interface QRScanViewController ()

@end

@implementation QRScanViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.captureSession = nil;
// 设置扫描界面
self.viewPreview = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.origin.x,self.view.frame.origin.y,self.view.frame.size.width,self.view.frame.size.height)];

[self.view addSubview:self.viewPreview];

//开始扫描
[self startReading];

}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(BOOL) startReading
{
NSError *error;
//1.初始化捕捉设备(AVCaptureDevice),类型为AVMediaTypeVideo
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//2.用captureDevice创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
}
//3.创建媒体数据输出流
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
//4.实例化捕捉会话
_captureSession = [[AVCaptureSession alloc] init];
//4.1.将输入流添加到会话
[_captureSession addInput:input];
//4.2.将媒体输出流添加到会话中
[_captureSession addOutput:captureMetadataOutput];
//5.创建串行队列,并加媒体输出流添加到队列当中
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
//5.1.设置代理
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
//5.2.设置输出媒体数据类型,此处设置了多个条形码及二维码的类型
[captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeQRCode]];
//6.实例化预览图层
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
//7.设置预览图层填充方式
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//8.设置图层的frame
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
//9.将图层添加到预览view的图层上
[_viewPreview.layer addSublayer:_videoPreviewLayer];
//10.设置扫描范围
captureMetadataOutput.rectOfInterest = CGRectMake(0.2f, 0.2f, 0.8f, 0.8f);
//10.1.扫描框
_boxView = [[UIView alloc] initWithFrame:CGRectMake(_viewPreview.bounds.size.width * 0.2f, _viewPreview.bounds.size.height * 0.2f, _viewPreview.bounds.size.width - _viewPreview.bounds.size.width * 0.4f, _viewPreview.bounds.size.height - _viewPreview.bounds.size.height * 0.4f)];
_boxView.layer.borderColor = [UIColor greenColor].CGColor;
_boxView.layer.borderWidth = 1.0f;
[_viewPreview addSubview:_boxView];//10.开始扫描
[_captureSession startRunning];
return YES;
}

#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]||
[[metadataObj type] isEqualToString:AVMetadataObjectTypeEAN13Code]||
[[metadataObj type] isEqualToString:AVMetadataObjectTypeEAN8Code]||
[[metadataObj type] isEqualToString:AVMetadataObjectTypeCode128Code]||
[[metadataObj type] isEqualToString:AVMetadataObjectTypeCode39Code]
) {
NSString *code = [metadataObj stringValue];
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
NSLog(@"send:%@",code);
//此地方是为了保证ui运行在主线程中。
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate ReadScan:code];
[self dismissViewControllerAnimated:YES completion:nil];
});

}

}
}

-(void) stopReading
{
[self.captureSession stopRunning];
self.captureSession = nil;
//[self.scanLayer removeFromSuperlayer];
[self.videoPreviewLayer removeFromSuperlayer];
}


3.新建主界面,添加按钮和标签

使用代理

@interface ViewController : UIViewController <QRScanDelegate>


启动扫描

QRScanViewController *scan = [[QRScanViewController alloc] init];
scan.delegate = self;
[self presentModalViewController:scan animated:NO];


实现代理方法

-(void)ReadScan:(NSString *)codetext
{
self.txtTxm.text = codetext;
NSLog(@"recvcode:%@",codetext);
}


总结:

第一是要注意条形码的类型。

第二是保证让ui运行在主线程中,不然会有延时。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: