掃描二維碼控件的封裝iOS實現
更新時間:2016年08月10日 10:03:57 作者:YouXianMing
這篇文章主要為大家詳細介紹了iOS實現掃描二維碼控件的封裝,具有一定的實用性和參考價值,感興趣的小伙伴們可以參考一下
掃描二維碼效果

源碼:https://github.com/YouXianMing/Animations
// // QRCodeView.h // QRCode // // Created by YouXianMing on 16/7/7. // Copyright © 2016年 XianMing You. All rights reserved. // #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @class QRCodeView; @protocol QRCodeViewDelegate <NSObject> @optional /** * 獲取QR的掃描結果 * * @param codeView QRCodeView實體對象 * @param codeString 掃描字符串 */ - (void)QRCodeView:(QRCodeView *)codeView codeString:(NSString *)codeString; @end @interface QRCodeView : UIView /** * 代理 */ @property (nonatomic, weak) id <QRCodeViewDelegate> delegate; /** * 燈的狀態(tài),默認為關閉 */ @property (nonatomic) AVCaptureTorchMode torchMode; /** * 敏感區(qū)域,如果不設置,則為全部掃描區(qū)域 */ @property (nonatomic) CGRect interestArea; /** * 你用來添加自定義控件的view,尺寸與當前初始化的view一致 */ @property (nonatomic, strong) UIView *contentView; /** * 正在運行當中 */ @property (nonatomic, readonly) BOOL isRunning; /** * 開始掃描 * * @return 如果成功,則返回YES,否則返回NO */ - (BOOL)start; /** * 結束掃描 */ - (void)stop; @end
//
// QRCodeView.m
// QRCode
//
// Created by YouXianMing on 16/7/7.
// Copyright © 2016年 XianMing You. All rights reserved.
//
#import "QRCodeView.h"
@interface QRCodeView () <AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic) BOOL isRunning;
@property (nonatomic, strong) UIView *videoView;
@property (nonatomic, strong) AVCaptureDeviceInput *deviceInput;
@property (nonatomic, strong) AVCaptureDevice *captureDevice;
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (nonatomic, strong) AVCaptureMetadataOutput *captureMetadataOutput;
@end
@implementation QRCodeView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.videoView = [[UIView alloc] initWithFrame:self.bounds];
[self addSubview:self.videoView];
self.contentView = [[UIView alloc] initWithFrame:self.bounds];
[self addSubview:self.contentView];
self.captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
_torchMode = AVCaptureTorchModeOff;
[self addNotificationCenter];
}
return self;
}
#pragma mark - NSNotificationCenter related.
- (void)addNotificationCenter {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(notificationCenterEvent:)
name:AVCaptureInputPortFormatDescriptionDidChangeNotification
object:nil];
}
- (void)removeNotificationCenter {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVCaptureInputPortFormatDescriptionDidChangeNotification
object:nil];
}
- (void)notificationCenterEvent:(NSNotification *)sender {
if (self.interestArea.size.width && self.interestArea.size.height) {
self.captureMetadataOutput.rectOfInterest = [self.videoPreviewLayer metadataOutputRectOfInterestForRect:self.interestArea];
} else {
self.captureMetadataOutput.rectOfInterest = CGRectMake(0, 0, 1, 1);
}
}
#pragma mark - Start & Stop.
- (BOOL)start {
// 初始化輸入流
BOOL result = NO;
NSError *error = nil;
self.deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:&error];
if (self.deviceInput == nil) {
NSLog(@"%@", error);
return result;
}
// 創(chuàng)建會話
self.captureSession = [[AVCaptureSession alloc] init];
// 添加輸入流
[self.captureSession addInput:self.deviceInput];
// 初始化輸出流
self.captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
// 添加輸出流
[self.captureSession addOutput:self.captureMetadataOutput];
// 創(chuàng)建queue.
[self.captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatch_queue_create(nil, nil)];
self.captureMetadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
// 創(chuàng)建輸出對象
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
self.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.videoPreviewLayer.frame = self.contentView.bounds;
[self.videoView.layer addSublayer:self.videoPreviewLayer];
// 開始
[self.captureSession startRunning];
self.isRunning = YES;
result = YES;
return result;
}
- (void)stop {
[self.captureSession stopRunning];
self.isRunning = NO;
self.captureSession = nil;
}
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
fromConnection:(AVCaptureConnection *)connection {
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *metadata = metadataObjects.firstObject;
NSString *result = nil;
if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {
result = metadata.stringValue;
if (_delegate && [_delegate respondsToSelector:@selector(QRCodeView:codeString:)]) {
[_delegate QRCodeView:self codeString:result];
}
}
}
}
#pragma mark - Setter & Getter.
- (void)setTorchMode:(AVCaptureTorchMode)torchMode {
_torchMode = torchMode;
if (_deviceInput && [self.captureDevice hasTorch]) {
[self.captureDevice lockForConfiguration:nil];
[self.captureDevice setTorchMode:torchMode];
[self.captureDevice unlockForConfiguration];
}
}
#pragma mark - System method.
- (void)dealloc {
[self stop];
[self removeNotificationCenter];
}
@end
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
詳解iOS開發(fā)中使用storyboard創(chuàng)建導航控制器的方法
這篇文章主要介紹了iOS開發(fā)中使用storyboard創(chuàng)建導航控制器的方法,包括對控制器聲明周期的控制介紹,代碼基于傳統的Objective-C,需要的朋友可以參考下2016-01-01
iOS中tableview實現編輯、全選及刪除等功能的方法示例
這篇文章主要給大家介紹了關于iOS中tableview實現編輯、全選及刪除等功能的相關資料,文中通過示例代碼介紹的非常詳細,不僅是介紹實現的方法,將實現過程中遇到的問題也都分享出來了,需要的朋友們下面來一起看看吧。2017-07-07
Objective-C的UIStackView常用屬性函數學習筆記
這篇文章主要為大家介紹了Objective-C的UIStackView常用屬性函數學習筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
IOS 簽名錯誤codesign failed with exit code 1解決方法
這篇文章主要介紹了IOS 簽名錯誤codesign failed with exit code 1解決方法的相關資料,遇到同樣問題的朋友可以看下,這里提供了解決方案,需要的朋友可以參考下2017-01-01
iOS中使用NSProgress類來創(chuàng)建UI進度條的方法詳解
NSProgress是iOS7以后引入的用于制作進度條的類,能夠監(jiān)聽多個任務,這里就為大家?guī)韎OS中使用NSProgress類來創(chuàng)建UI進度條的方法詳解,需要的朋友可以參考下2016-06-06

