注意:本篇文章采用了IOS7的新特性来扫二维码,所以系统支持要IOS7以上,如果要兼容IOS7之前的版本,自行找库来支持。
为了方便,我把扫二维码简单封装到了一个UIView中,用代理的方式返回值
在使用之前,应当为工程添加AVFoundation.framework
完整的实现代码
头文件
代码语言:javascript复制//
// HwcScanQRView.h
// HwcAnimationExample
//
// Created by huangwenchen on 15/1/7.
// Copyright (c) 2015年 huangwenchen. All rights reserved.
//
import <UIKit/UIKit.h>
@protocol HwcScanQRDelegate <NSObject>
/*!
@discussion Delegate method when scan QR successed
@param QRContent Scan result
@return Void
*/
-(void)DidGetScanWithResult:(NSString )QRContent;
/!
@discussion Delegate method when scan QR failed
@param error Error message
@return Void
/
-(void)DidFailToScanWithError:(NSError )error;
@end
@interface HwcScanQRView : UIView
@property id<HwcScanQRDelegate> delegate;
@property(nonatomic,readonly) bool isScaning;
-(BOOL)startScaning;
-(void)stop;
@end
</pre> .m文件
//
// HwcScanQRView.m
// HwcAnimationExample
//
// Created by huangwenchen on 15/1/7.
// Copyright (c) 2015年 huangwenchen. All rights reserved.
//
import "HwcScanQRView.h"
import <AVFoundation/AVFoundation.h>
@interface HwcScanQRView()<AVCaptureMetadataOutputObjectsDelegate>
@property(nonatomic,readwrite) bool isScaning;
@property(strong,nonatomic)AVCaptureSession captureSession;
@property(strong,nonatomic)AVCaptureVideoPreviewLayer vedioPreviewLayer;
@end
@implementation HwcScanQRView
pragma mark - Propertys
-(AVCaptureSession *)captureSession{
if (!_captureSession) {
_captureSession = [[AVCaptureSession alloc] init];
}
return _captureSession;
}
-(AVCaptureVideoPreviewLayer *)vedioPreviewLayer{
if (!_vedioPreviewLayer) {
_vedioPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
}
return _vedioPreviewLayer;
}
pragma mark - QRScan function
-(BOOL)startScaning{
NSError error;
AVCaptureDevice captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!deviceInput) {
if ([self.delegate respondsToSelector:@selector(DidFailToScanWithError:)]) {
[self.delegate DidFailToScanWithError:error];
}
return NO;
}
[self.captureSession addInput:deviceInput];
AVCaptureMetadataOutput captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:captureMetadataOutput];
dispatch_queue_t scanQRqueue;
scanQRqueue = dispatch_queue_create("scanQRqueue",DISPATCH_QUEUE_SERIAL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:scanQRqueue];
[captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
[self.vedioPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[self.vedioPreviewLayer setFrame:self.layer.bounds];
[self.layer addSublayer:self.vedioPreviewLayer];
[self.captureSession startRunning];
return YES;
}
-(void)stop{
[self.captureSession stopRunning];
self.isScaning = NO;
self.captureSession = nil;
[_vedioPreviewLayer removeFromSuperlayer];
}
pragma mark - AVFoundation delegate method
-(void)captureOutput:(AVCaptureOutput )captureOutput didOutputMetadataObjects:(NSArray )metadataObjects fromConnection:(AVCaptureConnection )connection
{
if (metadataObjects != nil && metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject metadataObject = [metadataObjects firstObject];
if ([[metadataObject type] isEqualToString:AVMetadataObjectTypeQRCode]) {
NSString * scanResult = [metadataObject stringValue];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.delegate respondsToSelector:@selector(DidGetScanWithResult:)]) {
[self.delegate DidGetScanWithResult:scanResult];
}
});
}
}
}
@end
</pre>
在使用的类中
//
// ViewController.m
// HwcAnimationExample
//
// Created by huangwenchen on 15/1/6.
// Copyright (c) 2015年 huangwenchen. All rights reserved.
//
import "ViewController.h"
import "HwcScanQRView.h"
@interface ViewController ()<HwcScanQRDelegate>//这里实现代理
@property (strong,nonatomic)UILabel * scanresultLabel;
@end
@implementation ViewController
(void)viewDidLoad {
[super viewDidLoad];
HwcScanQRView scanView = [[HwcScanQRView alloc] initWithFrame:CGRectMake(100,100,200, 200)];
scanView.delegate = self;//这一步必须的
[self.view addSubview:scanView];
self.scanresultLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 320, 200, 30)];
[self.view addSubview:self.scanresultLabel];
[scanView startScaning];//不要忘记开始扫描
}
//两个代理方法
-(void)DidGetScanWithResult:(NSString )QRContent{
self.scanresultLabel.text = QRContent;
}
-(void)DidFailToScanWithError:(NSError *)error{
NSLog(@"%@",error.localizedDescription);
}
@end</pre>