Authored by 于良

增加二维码、条形码扫码功能 review by 孙凯

... ... @@ -31,6 +31,14 @@
87561E4B1D0D519600C6AEE8 /* jquery-1.9.1.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 87561E471D0D519600C6AEE8 /* jquery-1.9.1.min.js */; };
87561E581D0FB54300C6AEE8 /* libSMXCrashlytics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87561E571D0FB4FD00C6AEE8 /* libSMXCrashlytics.a */; };
87561E591D0FB54900C6AEE8 /* libSMXCrashlytics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87561E571D0FB4FD00C6AEE8 /* libSMXCrashlytics.a */; };
8780A42C1EF279D5009FD234 /* UIAlertView+BBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A4241EF279D5009FD234 /* UIAlertView+BBlock.m */; };
8780A42D1EF279D5009FD234 /* YH_AVScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A4261EF279D5009FD234 /* YH_AVScanViewController.m */; };
8780A42E1EF279D5009FD234 /* YH_QRCodeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A4281EF279D5009FD234 /* YH_QRCodeHelper.m */; };
8780A42F1EF279D5009FD234 /* YH_ScanUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A42A1EF279D5009FD234 /* YH_ScanUtility.m */; };
8780A4311EF27AE6009FD234 /* UIAlertView+BBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A4241EF279D5009FD234 /* UIAlertView+BBlock.m */; };
8780A4321EF27AE6009FD234 /* YH_AVScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A4261EF279D5009FD234 /* YH_AVScanViewController.m */; };
8780A4331EF27AE6009FD234 /* YH_QRCodeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A4281EF279D5009FD234 /* YH_QRCodeHelper.m */; };
8780A4341EF27AE6009FD234 /* YH_ScanUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8780A42A1EF279D5009FD234 /* YH_ScanUtility.m */; };
87AF818B1CFD959D00ACE834 /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87AF818A1CFD959D00ACE834 /* libRNDeviceInfo.a */; };
87AF81B21D01168400ACE834 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87AF81B01D01168400ACE834 /* libReact.a */; };
87AF81B31D01168400ACE834 /* libSSZipArchive.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87AF81B11D01168400ACE834 /* libSSZipArchive.a */; };
... ... @@ -78,6 +86,14 @@
87561E461D0D519600C6AEE8 /* highcharts.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = highcharts.js; sourceTree = "<group>"; };
87561E471D0D519600C6AEE8 /* jquery-1.9.1.min.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "jquery-1.9.1.min.js"; sourceTree = "<group>"; };
87561E521D0FB4FD00C6AEE8 /* SMXCrashlytics.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SMXCrashlytics.xcodeproj; path = "../node_modules/react-native-fabric/ios/SMXCrashlytics.xcodeproj"; sourceTree = "<group>"; };
8780A4231EF279D5009FD234 /* UIAlertView+BBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+BBlock.h"; sourceTree = "<group>"; };
8780A4241EF279D5009FD234 /* UIAlertView+BBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+BBlock.m"; sourceTree = "<group>"; };
8780A4251EF279D5009FD234 /* YH_AVScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_AVScanViewController.h; sourceTree = "<group>"; };
8780A4261EF279D5009FD234 /* YH_AVScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_AVScanViewController.m; sourceTree = "<group>"; };
8780A4271EF279D5009FD234 /* YH_QRCodeHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_QRCodeHelper.h; sourceTree = "<group>"; };
8780A4281EF279D5009FD234 /* YH_QRCodeHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_QRCodeHelper.m; sourceTree = "<group>"; };
8780A4291EF279D5009FD234 /* YH_ScanUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_ScanUtility.h; sourceTree = "<group>"; };
8780A42A1EF279D5009FD234 /* YH_ScanUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_ScanUtility.m; sourceTree = "<group>"; };
87AF818A1CFD959D00ACE834 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libRNDeviceInfo.a; path = "../../../../Library/Developer/Xcode/DerivedData/YH_Vendor-hikjhmoukakxyvegrfxjqofhevhj/Build/Products/Release-iphonesimulator/libRNDeviceInfo.a"; sourceTree = "<group>"; };
87AF81B01D01168400ACE834 /* libReact.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libReact.a; path = "Pods/../build/Debug-iphoneos/libReact.a"; sourceTree = "<group>"; };
87AF81B11D01168400ACE834 /* libSSZipArchive.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSSZipArchive.a; path = "Pods/../build/Debug-iphoneos/libSSZipArchive.a"; sourceTree = "<group>"; };
... ... @@ -142,6 +158,7 @@
13B07FAE1A68108700A75B9A /* YH_Vendor */ = {
isa = PBXGroup;
children = (
8780A41F1EF279D5009FD234 /* QRCode */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
... ... @@ -229,6 +246,22 @@
name = Products;
sourceTree = "<group>";
};
8780A41F1EF279D5009FD234 /* QRCode */ = {
isa = PBXGroup;
children = (
8780A4231EF279D5009FD234 /* UIAlertView+BBlock.h */,
8780A4241EF279D5009FD234 /* UIAlertView+BBlock.m */,
8780A4251EF279D5009FD234 /* YH_AVScanViewController.h */,
8780A4261EF279D5009FD234 /* YH_AVScanViewController.m */,
8780A4271EF279D5009FD234 /* YH_QRCodeHelper.h */,
8780A4281EF279D5009FD234 /* YH_QRCodeHelper.m */,
8780A4291EF279D5009FD234 /* YH_ScanUtility.h */,
8780A42A1EF279D5009FD234 /* YH_ScanUtility.m */,
);
name = QRCode;
path = YH_Vendor/QRCode;
sourceTree = "<group>";
};
D5ECECDEB080EA5509812B91 /* Frameworks */ = {
isa = PBXGroup;
children = (
... ... @@ -319,6 +352,10 @@
CreatedOnToolsVersion = 6.2;
TestTargetID = 13B07F861A680F5B00A75B9A;
};
8730DB7C1D07ED1900EC80BA = {
DevelopmentTeam = 6U82P566A4;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "YH_Vendor" */;
... ... @@ -550,9 +587,13 @@
buildActionMask = 2147483647;
files = (
2E572BF51D00089000B89A37 /* RNAutoUpdater.m in Sources */,
8780A42D1EF279D5009FD234 /* YH_AVScanViewController.m in Sources */,
8780A42E1EF279D5009FD234 /* YH_QRCodeHelper.m in Sources */,
2EDB1CE11CFED97B001CA832 /* RNNativeConfig.m in Sources */,
8780A42C1EF279D5009FD234 /* UIAlertView+BBlock.m in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
8780A42F1EF279D5009FD234 /* YH_ScanUtility.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
... ... @@ -560,6 +601,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8780A4311EF27AE6009FD234 /* UIAlertView+BBlock.m in Sources */,
8780A4321EF27AE6009FD234 /* YH_AVScanViewController.m in Sources */,
8780A4331EF27AE6009FD234 /* YH_QRCodeHelper.m in Sources */,
8780A4341EF27AE6009FD234 /* YH_ScanUtility.m in Sources */,
8730DB7F1D07ED1900EC80BA /* RNAutoUpdater.m in Sources */,
8730DB801D07ED1900EC80BA /* RNNativeConfig.m in Sources */,
8730DB811D07ED1900EC80BA /* AppDelegate.m in Sources */,
... ... @@ -782,7 +827,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = 6U82P566A4;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
... ... @@ -801,7 +848,8 @@
);
PRODUCT_BUNDLE_IDENTIFIER = cn.yoho.vendor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "0d243fd2-5d46-45ea-9bb4-545abd518e87";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Debug;
};
... ... @@ -813,6 +861,7 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = 6U82P566A4;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
... ... @@ -831,7 +880,8 @@
);
PRODUCT_BUNDLE_IDENTIFIER = cn.yoho.vendor;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "0d243fd2-5d46-45ea-9bb4-545abd518e87";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Release;
};
... ...
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "贩售通-58.png",
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "cameraQR5@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "cameraQRLine@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"images" : [
{
"idiom" : "universal",
"filename" : "favoites_barButtonItemiconCancel_normal.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "favoites_barButtonItemiconCancel_normal@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
... ... @@ -57,5 +57,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSCameraUsageDescription</key>
<string>使用相机</string>
</dict>
</plist>
... ...
//
// UIAlertView+BBlock.h
// BBlock
//
// Created by Dominic Tham on 5/14/12.
// Updated by David Keegan on 6/4/12.
//
#import <UIKit/UIKit.h>
@interface UIAlertView(BBlock)
typedef void (^UIAlertViewBBlock)(NSInteger buttonIndex, UIAlertView *alertView);
- (void)setCompletionBlock:(UIAlertViewBBlock)block;
- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelTitle
otherButtonTitle:(NSString *)otherButtonTitle completionBlock:(UIAlertViewBBlock)block;
@end
... ...
//
// UIAlertView+BBlock.m
// BBlock
//
// Created by Dominic Tham on 5/14/12.
// Updated by David Keegan on 6/4/12.
//
#import "UIAlertView+BBlock.h"
#import <objc/runtime.h>
static char UIAlertViewDelegateBBlockKey;
@interface UIAlertViewBBlockDelegate : NSObject
<UIAlertViewDelegate>
@property (strong, nonatomic) UIAlertViewBBlock block;
@end
@implementation UIAlertViewBBlockDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(self.block){
self.block(buttonIndex, alertView);
}
}
@end
@implementation UIAlertView(BBlock)
- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)cancelTitle
otherButtonTitle:(NSString *)otherButtonTitle completionBlock:(UIAlertViewBBlock)block{
if((self = [self initWithTitle:title message:message delegate:nil
cancelButtonTitle:cancelTitle otherButtonTitles:otherButtonTitle, nil])){
[self setCompletionBlock:block];
return self;
}
return nil;
}
- (void)setCompletionBlock:(UIAlertViewBBlock)block{
UIAlertViewBBlockDelegate *alertViewDelegate = [[UIAlertViewBBlockDelegate alloc] init];
objc_setAssociatedObject(self, &UIAlertViewDelegateBBlockKey, alertViewDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
alertViewDelegate.block = block;
self.delegate = alertViewDelegate;
}
@end
... ...
//
// YH_AVScanViewController.h
// YH_Mall
//
// Created by XingYaXin on 14-9-18.
// Copyright (c) 2014年 YOHO. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
typedef NS_ENUM(NSInteger, YHScanType){
YHScanType_Express, //快递单号扫描
};
typedef void(^ScanResultCallbackBlock)(NSString *info);
@interface YH_AVScanViewController : UIViewController<AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic, assign) YHScanType scanType;
@property (copy, nonatomic) ScanResultCallbackBlock resultCallBack;
@end
... ...
//
// YH_AVScanViewController.m
// YH_Mall
//
// Created by XingYaXin on 14-9-18.
// Copyright (c) 2014年 YOHO. All rights reserved.
//
#import "YH_AVScanViewController.h"
#import "YH_ScanUtility.h"
#import "UIAlertView+BBlock.h"
#define is3_5Inches ([[UIScreen mainScreen] bounds].size.height == 480)
#define IsNilOrNull(_ref) (((_ref) == nil) || ([(_ref) isEqual:[NSNull null]]))
#define IsDictionaryClass(_ref) (!IsNilOrNull(_ref) && ([(_ref) isKindOfClass:[NSDictionary class]]))
#define IsArrayClass(_ref) (!IsNilOrNull(_ref) && ([(_ref) isKindOfClass:[NSArray class]]))
#define IsStrEmpty(_ref) (IsNilOrNull(_ref) || (![(_ref) isKindOfClass:[NSString class]]) || ([(_ref) isEqualToString:@""]))
#define kScanWindowTop (is3_5Inches ? 80.0f : 95.0f)
#define kScanWindowWidth (220.f)
#define kScanWindowLeft (50.f)
#define kScanWindowLineStep (2)
#define kScanToolbarHeight (44.f)
#define KSknString @"skn="
#define kBrandIdString @"brand_id="
#define kPCLoginCodeString @"qr="
////////////////////////
static CGFloat const kIntroductionOriginX = 75.0f; //introudction数据
static CGFloat const kIntroductionOriginY = 350.0f;
static CGFloat const kIntroductionWidth = 170.0f;
static CGFloat const kIntroductionHeight = 20.0f;
static CGFloat const kScanLineOriginX = 50.0f;
static CGFloat const kScanLineWidth = 220.0f;
static CGFloat const kScanLineHeight = 2.0f;
static CGFloat const ktoolBarViewHeight = 44.0f; //toolBarView高度
static CGFloat const kCloseZBarOriginX = 10.0f; //closeZBar关闭按钮X值
@interface YH_AVScanViewController ()
{
NSInteger numberCount;
BOOL upOrdown;
NSTimer * timerHandle;
}
@property (strong, nonatomic) UIImageView *scanLine;
@property (strong, nonatomic) UIView *toolBarView;
@property (strong, nonatomic) UILabel *introudction;
@property (strong, nonatomic) UIImageView *maskImageView;
@property (copy, nonatomic) NSString *scanInfoString; //扫描信息全局变量
@property (strong, nonatomic) YH_ScanUtility *scanUtility;
@property (assign, nonatomic) dispatch_once_t onceToken;
@property (assign, nonatomic) NSInteger kNumberCount; //扫描计数器
@end
@implementation YH_AVScanViewController
- (YH_ScanUtility *)scanUtility
{
if (!_scanUtility) {
_scanUtility = [[YH_ScanUtility alloc] init];
}
return _scanUtility;
}
- (id)init{
self = [super init];
if (self) {
self.scanType = YHScanType_Express;
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
upOrdown = NO;
numberCount = 0;
self.kNumberCount = is3_5Inches ? 170 : 200;
__weak typeof(self) weakSelf = self;
[self.scanUtility addScanCallBackHandle:^(NSString *info, NSError *error) {
[weakSelf dispatchQRByScanString:info];
}];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setupCamera) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self setupCamera];
}
- (void)addCustomeViews:(UIView *)containView
{
[self addScanMask:containView];
[self addHelpInfo:containView];
[self addToolBar:containView];
}
- (void)addHelpInfo:(UIView *)currentView{
if (self.scanType == YHScanType_Express) {
self.introudction.text = @"尽量让二维码/条形码充满框内";
self.introudction.frame = CGRectMake(kIntroductionOriginX, kIntroductionOriginY, kIntroductionWidth+30, kIntroductionHeight);
self.introudction.center = CGPointMake(self.view.center.x, kIntroductionOriginY * kScreenPointScale);
}
[currentView addSubview:self.introudction];
[currentView addSubview:self.scanLine];
if (!timerHandle) {
timerHandle = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(scanAnimation) userInfo:nil repeats:YES];
}
}
- (void)addToolBar:(UIView *)currentView{
[currentView addSubview:self.toolBarView];
}
- (void)addScanMask:(UIView *)currentView{
[currentView addSubview:self.maskImageView];
}
- (void)scanAnimation{
if (upOrdown == NO) {
numberCount ++;
self.scanLine.frame = CGRectMake( kScanWindowLeft, kScanWindowTop + kScanWindowLineStep * numberCount, kScanWindowWidth, 2);
self.scanLine.center = CGPointMake(self.view.center.x, (kScanWindowTop + kScanWindowLineStep * numberCount) * kScreenPointScale);
if (kScanWindowLineStep * numberCount == self.kNumberCount) {
upOrdown = YES;
}
}
else {
numberCount --;
self.scanLine.frame = CGRectMake( kScanWindowLeft, kScanWindowTop + kScanWindowLineStep * numberCount, kScanWindowWidth, 2);
self.scanLine.center = CGPointMake(self.view.center.x, (kScanWindowTop + kScanWindowLineStep * numberCount) * kScreenPointScale);
if (numberCount == 0) {
upOrdown = NO;
}
}
}
- (void)backAction:(id)sender
{
if ([timerHandle isValid]) {
[timerHandle invalidate];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)setupCamera
{
[self.scanUtility resetCamera];
[self.view.layer addSublayer:self.scanUtility.previewLayer];
[self addCustomeViews:self.view];
}
- (void)dispatchQRByScanString:(NSString *)scanQRString{
switch (self.scanType) {
case YHScanType_Express:{
[self scanExpress:scanQRString];
return;
}
break;
default:
break;
}
}
- (BOOL)scanExpress:(NSString *)expressString
{
if (IsStrEmpty(expressString)) {
[self showAlertAndReinit:[NSString stringWithFormat:@"快递单号无法识别:%@",expressString]];
return NO;
}
[timerHandle invalidate];
[self dismissViewControllerAnimated:YES completion:^(void){
if (self.resultCallBack) {
self.resultCallBack(expressString);
}
}];
return YES;
}
- (void)showAlertAndReinit:(NSString *)alertString{
__weak typeof(self) weakSelf = self;
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"二维码扫描"
message:alertString
cancelButtonTitle:@"确定"
otherButtonTitle:nil
completionBlock:^(NSInteger buttonIndex, UIAlertView *alertView){
[weakSelf setupCamera];
}];
[av show];
}
#pragma mark - init
- (UIImageView *)scanLine
{
if (IsNilOrNull(_scanLine)) {
_scanLine = [[UIImageView alloc] initWithFrame:CGRectMake(kScanLineOriginX, kScanWindowTop, kScanLineWidth, kScanLineHeight)];
_scanLine.center = CGPointMake(self.view.center.x, kScanWindowTop * kScreenPointScale);
_scanLine.image = [UIImage imageNamed:@"cameraQRLine.png"];
}
return _scanLine;
}
- (UILabel *)introudction{
if (IsNilOrNull(_introudction)) {
_introudction = [[UILabel alloc] initWithFrame:CGRectMake(kIntroductionOriginX, kIntroductionOriginY, kIntroductionWidth, kIntroductionHeight)];
_introudction.center = CGPointMake(self.view.center.x, kIntroductionOriginY * kScreenPointScale);
_introudction.backgroundColor = [UIColor grayColor];
_introudction.layer.cornerRadius = 10.0f;
_introudction.clipsToBounds = YES;
_introudction.numberOfLines = 1;
_introudction.textColor = [UIColor blackColor];
_introudction.font = [UIFont systemFontOfSize:14.0f];
_introudction.textAlignment = NSTextAlignmentCenter;
_introudction.text = @"尽量让二维码/条形码充满框内";
}
return _introudction;
}
- (UIView *)toolBarView{
if (IsNilOrNull(_toolBarView)) {
_toolBarView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, [[UIScreen mainScreen] bounds].size.height - ktoolBarViewHeight, self.view.frame.size.width, ktoolBarViewHeight)];
UIButton *closeZBar = [UIButton buttonWithType:UIButtonTypeCustom];
[closeZBar setImage:[UIImage imageNamed:@"favoites_barButtonItemiconCancel_normal"] forState:UIControlStateNormal];
[closeZBar addTarget:self action:@selector(backAction:) forControlEvents:UIControlEventTouchUpInside];
closeZBar.frame = CGRectMake(kCloseZBarOriginX, 0.0f, ktoolBarViewHeight, ktoolBarViewHeight);
[_toolBarView addSubview:closeZBar];
_toolBarView.backgroundColor = [UIColor blackColor];
}
return _toolBarView;
}
- (UIImageView *)maskImageView{
if (IsNilOrNull(_maskImageView)) {
_maskImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
[_maskImageView setImage:[UIImage imageNamed:@"cameraQR5"]];
}
return _maskImageView;
}
@end
... ...
//
// YH_QRCodeHelper.h
// YH_Mall
//
// Created by redding on 16/8/29.
// Copyright © 2016年 YOHO. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"
@interface YH_QRCodeHelper : NSObject <RCTBridgeModule>
@end
... ...
//
// YH_QRCodeHelper.m
// YH_Mall
//
// Created by redding on 16/8/29.
// Copyright © 2016年 YOHO. All rights reserved.
//
#import "YH_QRCodeHelper.h"
#import "RCTEventDispatcher.h"
#import "YH_AVScanViewController.h"
#import "AppDelegate.h"
@implementation YH_QRCodeHelper
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
RCT_REMAP_METHOD(displayQRScanner, displayQRScannerWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
YH_AVScanViewController *avscanViewController = [[YH_AVScanViewController alloc] init];
avscanViewController.scanType = YHScanType_Express;
[avscanViewController.view setFrame:[[UIScreen mainScreen] bounds]];
avscanViewController.resultCallBack = ^(NSString *info) {
resolve(info);
};
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.window.rootViewController presentViewController:avscanViewController animated:YES completion:^{}];
});
}
@end
... ...
//
// YH_ScanUtility.h
// YH_Mall
//
// Created by Cloud on 15/4/10.
// Copyright (c) 2015年 YOHO. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#define kScreenPointScale CGRectGetWidth([[UIScreen mainScreen] bounds])/320.0f
#define kScreenPoint6Scale CGRectGetWidth([[UIScreen mainScreen] bounds])/375.0f
#define kScreenWidth ([[UIScreen mainScreen] bounds].size.width)
#define kScreenHeight ([[UIScreen mainScreen] bounds].size.height)
typedef void (^StringBlock)(NSString *info, NSError *error);
@interface YH_ScanUtility : NSObject <AVCaptureMetadataOutputObjectsDelegate>
@property (assign, nonatomic) BOOL enableFlashLight;
@property (strong, nonatomic) AVCaptureDevice *device;
@property (strong, nonatomic) AVCaptureDeviceInput *input;
@property (strong, nonatomic) AVCaptureMetadataOutput *output;
@property (strong, nonatomic) AVCaptureSession *session;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;
- (void)addScanCallBackHandle:(StringBlock)scanCallBack;
- (void)resetCamera;
@end
... ...
//
// YH_ScanUtility.m
// YH_Mall
//
// Created by Cloud on 15/4/10.
// Copyright (c) 2015年 YOHO. All rights reserved.
//
#import "YH_ScanUtility.h"
#import <UIKit/UIKit.h>
@interface YH_ScanUtility ()
@property (copy, nonatomic) NSString *scanResultString;
@property (strong, nonatomic) StringBlock scanResultBlock;
@end
@implementation YH_ScanUtility
- (instancetype)init
{
self = [super init];
if (self) {
_enableFlashLight = NO;
}
return self;
}
- (void)addScanCallBackHandle:(StringBlock)scanCallBack
{
self.scanResultBlock = scanCallBack;
}
- (void)resetCamera
{
[self setupAVCamera];
}
- (void)setupAVCamera
{
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (self.enableFlashLight) {
if ([_device lockForConfiguration:nil]) {
// if ([_device respondsToSelector:@selector(setFlashMode:)]) {
// [_device setFlashMode:AVCaptureFlashModeOn];
// }
if ([_device respondsToSelector:@selector(setTorchMode:)]) {
[_device setTorchMode:AVCaptureTorchModeOn];
}
[_device setTorchModeOnWithLevel:AVCaptureMaxAvailableTorchLevel error:nil];
[_device unlockForConfiguration];
}
}
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
self.output = [[AVCaptureMetadataOutput alloc]init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// Session
self.session = [[AVCaptureSession alloc]init];
[_session setSessionPreset:AVCaptureSessionPresetHigh];
if ([_session canAddInput:self.input]){
[_session addInput:self.input];
} else {
return;
}
if ([_session canAddOutput:self.output]){
[_session addOutput:self.output];
} else {
return;
}
// 条码类型 AVMetadataObjectTypeQRCode
_output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.previewLayer.frame = [[UIScreen mainScreen] bounds];
_output.rectOfInterest = CGRectMake(0, 0, (175.f+220.f)*kScreenPointScale/kScreenHeight, (190.f+220.f)*kScreenPointScale/kScreenWidth);
[_session startRunning];
}
#pragma mark -
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
[_session stopRunning];
NSString *stringValue = nil;
if ([metadataObjects count] <= 0){
return;
}
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
stringValue = metadataObject.stringValue;
self.scanResultBlock(stringValue,nil);
}
@end
... ...
... ... @@ -57,5 +57,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSCameraUsageDescription</key>
<string>使用相机</string>
</dict>
</plist>
... ...