iOS 扫一扫功能实现 —— HERO博客
2017-02-20 18:40
337 查看
调用系统原生接口实现扫一扫功能,可扫描识别二维码、条形码,识别相册图片。
首先看一下效果图:
下面贴上代码:
(如果测试机系统10.0及以上,在Info.plist文件添加如下语句:Privacy - Camera Usage Description、Privacy - Photo Library Usage Description。
可参考我之前的一篇博客,iOS 10.0系统麦克风、相机等权限崩溃问题解决。)
AppDelegate.m:
ViewController:
HWScanViewController:
扫一扫Demo下载链接:http://code.cocoachina.com/view/134257
首先看一下效果图:
下面贴上代码:
(如果测试机系统10.0及以上,在Info.plist文件添加如下语句:Privacy - Camera Usage Description、Privacy - Photo Library Usage Description。
可参考我之前的一篇博客,iOS 10.0系统麦克风、相机等权限崩溃问题解决。)
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; }
ViewController:
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end /*** ---------------分割线--------------- ***/ #import "ViewController.h" #import "HWScanViewController.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; //创建控件 [self creatControl]; } - (void)creatControl { //扫一扫按钮 UIButton *scanBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 44)]; scanBtn.backgroundColor = [UIColor orangeColor]; [scanBtn setTitle:@"扫一扫" forState:UIControlStateNormal]; [scanBtn addTarget:self action:@selector(scanBtnOnClick) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:scanBtn]; } - (void)scanBtnOnClick { HWScanViewController *vc = [[HWScanViewController alloc] init]; [self.navigationController pushViewController:vc animated:YES]; } @end
HWScanViewController:
#import <UIKit/UIKit.h> @interface HWScanViewController : UIViewController @end /*** ---------------分割线--------------- ***/ #import "HWScanViewController.h" #import <AVFoundation/AVFoundation.h> #define KMainW [UIScreen mainScreen].bounds.size.width #define KMainH [UIScreen mainScreen].bounds.size.height @interface HWScanViewController ()<AVCaptureMetadataOutputObjectsDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate> @property (nonatomic, strong) NSTimer *timer; @property (nonatomic, strong) AVCaptureDevice *device; @property (nonatomic, strong) AVCaptureSession *session; @property (nonatomic, strong) AVCaptureVideoPreviewLayer *preview; @property (nonatomic, weak) UIImageView *line; @property (nonatomic, assign) NSInteger distance; @end @implementation HWScanViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化信息 [self initInfo]; //创建控件 [self creatControl]; //设置参数 [self setupCamera]; //添加定时器 [self addTimer]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self stopScanning]; } - (void)initInfo { //背景色 self.view.backgroundColor = [UIColor blackColor]; //导航标题 self.navigationItem.title = @"二维码/条形码"; //导航右侧相册按钮 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"相册" style:UIBarButtonItemStylePlain target:self action:@selector(photoBtnOnClick)]; } - (void)creatControl { CGFloat scanW = KMainW * 0.65; CGFloat padding = 10.0f; CGFloat labelH = 20.0f; CGFloat tabBarH = 64.0f; CGFloat cornerW = 26.0f; CGFloat marginX = (KMainW - scanW) * 0.5; CGFloat marginY = (KMainH - scanW - padding - labelH) * 0.5; //遮盖视图 for (int i = 0; i < 4; i++) { UIView *cover = [[UIView alloc] initWithFrame:CGRectMake(0, (marginY + scanW) * i, KMainW, marginY + (padding + labelH) * i)]; if (i == 2 || i == 3) { cover.frame = CGRectMake((marginX + scanW) * (i - 2), marginY, marginX, scanW); } cover.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f]; [self.view addSubview:cover]; } //扫描视图 UIView *scanView = [[UIView alloc] initWithFrame:CGRectMake(marginX, marginY, scanW, scanW)]; [self.view addSubview:scanView]; //扫描线 UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, scanW, 2)]; [self drawLineForImageView:line]; [scanView addSubview:line]; self.line = line; //边框 UIView *borderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, scanW, scanW)]; borderView.layer.borderColor = [[UIColor whiteColor] CGColor]; borderView.layer.borderWidth = 1.0f; [scanView addSubview:borderView]; //扫描视图四个角 for (int i = 0; i < 4; i++) { CGFloat imgViewX = (scanW - cornerW) * (i % 2); CGFloat imgViewY = (scanW - cornerW) * (i / 2); UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(imgViewX, imgViewY, cornerW, cornerW)]; if (i == 0 || i == 1) { imgV 4000 iew.transform = CGAffineTransformRotate(imgView.transform, M_PI_2 * i); }else { imgView.transform = CGAffineTransformRotate(imgView.transform, - M_PI_2 * (i - 1)); } [self drawImageForImageView:imgView]; [scanView addSubview:imgView]; } //提示标签 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(scanView.frame) + padding, KMainW, labelH)]; label.text = @"将二维码/条形码放入框内,即可自动扫描"; label.font = [UIFont systemFontOfSize:16.0f]; label.textAlignment = NSTextAlignmentCenter; label.textColor = [UIColor whiteColor]; [self.view addSubview:label]; //选项栏 UIView *tabBarView = [[UIView alloc] initWithFrame:CGRectMake(0, KMainH - tabBarH, KMainW, tabBarH)]; tabBarView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8f]; [self.view addSubview:tabBarView]; //开启照明按钮 UIButton *lightBtn = [[UIButton alloc] initWithFrame:CGRectMake(KMainW - 100, 0, 100, tabBarH)]; lightBtn.titleLabel.font = [UIFont systemFontOfSize:16.0f]; [lightBtn setTitle:@"开启照明" forState:UIControlStateNormal]; [lightBtn setTitle:@"关闭照明" forState:UIControlStateSelected]; [lightBtn addTarget:self action:@selector(lightBtnOnClick:) forControlEvents:UIControlEventTouchUpInside]; [tabBarView addSubview:lightBtn]; } - (void)setupCamera { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //初始化相机设备 _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //初始化输入流 AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil]; //初始化输出流 AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; //设置代理,主线程刷新 [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //初始化链接对象 _session = [[AVCaptureSession alloc] init]; //高质量采集率 [_session setSessionPreset:AVCaptureSessionPresetHigh]; if ([_session canAddInput:input]) [_session addInput:input]; if ([_session canAddOutput:output]) [_session addOutput:output]; //条码类型(二维码/条形码) output.metadataObjectTypes = [NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil]; //更新界面 dispatch_async(dispatch_get_main_queue(), ^{ _preview = [AVCaptureVideoPreviewLayer layerWithSession:_session]; _preview.videoGravity = AVLayerVideoGravityResizeAspectFill; _preview.frame = CGRectMake(0, 0, KMainW, KMainH); [self.view.layer insertSublayer:_preview atIndex:0]; [_session startRunning]; }); }); } - (void)addTimer { _distance = 0; self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(timerAction) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; } - (void)timerAction { if (_distance++ > KMainW * 0.65) _distance = 0; _line.frame = CGRectMake(0, _distance, KMainW * 0.65, 2); } - (void)removeTimer { [_timer invalidate]; _timer = nil; } //照明按钮点击事件 - (void)lightBtnOnClick:(UIButton *)btn { //判断是否有闪光灯 if (![_device hasTorch]) { [self showAlertWithTitle:@"当前设备没有闪光灯,无法开启照明功能" message:nil sureHandler:nil cancelHandler:nil]; return; } btn.selected = !btn.selected; [_device lockForConfiguration:nil]; if (btn.selected) { [_device setTorchMode:AVCaptureTorchModeOn]; }else { [_device setTorchMode:AVCaptureTorchModeOff]; } [_device unlockForConfiguration]; } //进入相册 - (void)photoBtnOnClick { if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { UIImagePickerController *controller = [[UIImagePickerController alloc] init]; controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; controller.delegate = self; [self presentViewController:controller animated:YES completion:nil]; }else { [self showAlertWithTitle:@"当前设备不支持访问相册" message:nil sureHandler:nil cancelHandler:nil]; } } #pragma mark - AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { //扫描完成 if ([metadataObjects count] > 0) { //停止扫描 [self stopScanning]; //显示结果 [self showAlertWithTitle:@"扫描结果" message:[[metadataObjects firstObject] stringValue] sureHandler:nil cancelHandler:nil]; } } - (void)stopScanning { [_session stopRunning]; _session = nil; [_preview removeFromSuperlayer]; [self removeTimer]; } #pragma mark - UIImagePickerControllrDelegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info { [picker dismissViewControllerAnimated:YES completion:^{ //获取相册图片 UIImage *image = info[UIImagePickerControllerOriginalImage]; //识别图片 CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}]; NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]]; //识别结果 if (features.count > 0) { [self showAlertWithTitle:@"扫描结果" message:[[features firstObject] messageString] sureHandler:nil cancelHandler:nil]; }else{ [self showAlertWithTitle:@"没有识别到二维码或条形码" message:nil sureHandler:nil cancelHandler:nil]; } }]; } //提示弹窗 - (void)showAlertWithTitle:(NSString *)title message:(NSString *)message sureHandler:(void (^)())sureHandler cancelHandler:(void (^)())cancelHandler { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:sureHandler]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:cancelHandler]; [alertController addAction:sureAction]; [alertController addAction:cancelAction]; [self presentViewController:alertController animated:YES completion:nil]; } //绘制角图片 - (void)drawImageForImageView:(UIImageView *)imageView { UIGraphicsBeginImageContext(imageView.bounds.size); //获取上下文 CGContextRef context = UIGraphicsGetCurrentContext(); //设置线条宽度 CGContextSetLineWidth(context, 6.0f); //设置颜色 CGContextSetStrokeColorWithColor(context, [[UIColor greenColor] CGColor]); //路径 CGContextBeginPath(context); //设置起点坐标 CGContextMoveToPoint(context, 0, imageView.bounds.size.height); //设置下一个点坐标 CGContextAddLineToPoint(context, 0, 0); CGContextAddLineToPoint(context, imageView.bounds.size.width, 0); //渲染,连接起点和下一个坐标点 CGContextStrokePath(context); imageView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } //绘制线图片 - (void)drawLineForImageView:(UIImageView *)imageView { CGSize size = imageView.bounds.size; UIGraphicsBeginImageContext(size); //获取上下文 CGContextRef context = UIGraphicsGetCurrentContext(); //创建一个颜色空间 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); //设置开始颜色 const CGFloat *startColorComponents = CGColorGetComponents([[UIColor greenColor] CGColor]); //设置结束颜色 const CGFloat *endColorComponents = CGColorGetComponents([[UIColor whiteColor] CGColor]); //颜色分量的强度值数组 CGFloat components[8] = {startColorComponents[0], startColorComponents[1], startColorComponents[2], startColorComponents[3], endColorComponents[0], endColorComponents[1], endColorComponents[2], endColorComponents[3] }; //渐变系数数组 CGFloat locations[] = {0.0, 1.0}; //创建渐变对象 CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2); //绘制渐变 CGContextDrawRadialGradient(context, gradient, CGPointMake(size.width * 0.5, size.height * 0.5), size.width * 0.25, CGPointMake(size.width * 0.5, size.height * 0.5), size.width * 0.5, kCGGradientDrawsBeforeStartLocation); //释放 CGColorSpaceRelease(colorSpace); CGGradientRelease(gradient); imageView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } @end
扫一扫Demo下载链接:http://code.cocoachina.com/view/134257
相关文章推荐
- iOS 答题功能实现 —— HERO博客
- iOS 浏览相册功能实现 —— HERO博客
- iOS 摇一摇功能实现 —— HERO博客
- iOS 基于CATransition实现翻页、旋转等动画效果 —— HERO博客
- iOS实现“摇一摇”与“扫一扫”功能
- iOS 使用NSMutableAttributedString实现不同颜色尺寸文字 —— HERO博客
- iOS实现“摇一摇”与“扫一扫”功能示例代码
- iOS实现“摇一摇”与“扫一扫”功能示例代码
- iOS 视频录制、播放,使用视听媒体框架AVFoundation实现视频录制播放 —— HERO博客
- iOS CAEmitterLayer简介,基于CAEmitterLayer实现粒子效果 —— HERO博客
- iOS 音频录制、播放,使用音频处理框架The Amazing Audio Engine实现音频录制播放 —— HERO博客
- iOS UICollectionView实现图片轮播 —— HERO博客
- ios扫一扫功能实现
- iOS UITextField实用实现手机账号344格式 —— HERO博客
- iOS 拍摄照片,使用视听媒体框架AVFoundation实现照片拍摄 —— HERO博客
- iOS 应用实现条形码扫描功能的方法
- ios实现条形码扫描功能
- iOS 应用实现条形码扫描功能的方法
- iOS 应用实现条形码扫描功能的方法
- ios录音功能的实现