首页 > 系统 > iOS > 正文

iOS实现“摇一摇”与“扫一扫”功能示例代码

2020-07-26 02:59:22
字体:
来源:转载
供稿:网友

“摇一摇”功能的实现:

iPhone对 “摇一摇”有很好的支持,总体说来就两步:

在视图控制器中打开接受“摇一摇”的开关;

 - (void)viewDidLoad {  // 设置允许摇一摇功能  [UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;  // 并让自己成为第一响应者  [self becomeFirstResponder];}

在“摇一摇”触发的制定的方法中实现需要实现的功能(”摇一摇“检测方法)。

// 摇一摇开始摇动 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {   NSLog(@"开始摇动");  //添加“摇一摇”动画  [self addAnimations];  //音效  AudioServicesPlaySystemSound (soundID);   return; } // “摇一摇”取消摇动 - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {   NSLog(@"取消摇动");   return; } // “摇一摇”摇动结束 - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {   if (event.subtype == UIEventSubtypeMotionShake) { // 判断是否是摇动结束     NSLog(@"摇动结束");   }   return; } 

”摇一摇“的动画效果:

- (void)addAnimations {  //音效  AudioServicesPlaySystemSound (soundID);  //让上面图片的上下移动  CABasicAnimation *translation2 = [CABasicAnimation animationWithKeyPath:@"position"];  translation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];  translation2.fromValue = [NSValue valueWithCGPoint:CGPointMake(160, 115)];  translation2.toValue = [NSValue valueWithCGPoint:CGPointMake(160, 40)];  translation2.duration = 0.4;  translation2.repeatCount = 1;  translation2.autoreverses = YES;  //让下面的图片上下移动  CABasicAnimation *translation = [CABasicAnimation animationWithKeyPath:@"position"];  translation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];  translation.fromValue = [NSValue valueWithCGPoint:CGPointMake(160, 345)];  translation.toValue = [NSValue valueWithCGPoint:CGPointMake(160, 420)];  translation.duration = 0.4;  translation.repeatCount = 1;  translation.autoreverses = YES;  [imgDown.layer addAnimation:translation forKey:@"translation"];  [imgUp.layer addAnimation:translation2 forKey:@"translation2"];  }

注意:在模拟器中运行时,可以通过「Hardware」-「Shake Gesture」来测试「摇一摇」功能。如下:

“扫一扫”功能的实现:

基于AVCaptureDevice做的二维码扫描器,基本步骤如下:

初始化相机,生成扫描器

 设置参数

 - (void)setupCamera {  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];    _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];    _output = [[AVCaptureMetadataOutput alloc]init];    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];    _session = [[AVCaptureSession alloc]init];    [_session setSessionPreset:AVCaptureSessionPresetHigh];    if ([_session canAddInput:self.input])    {      [_session addInput:self.input];    }    if ([_session canAddOutput:self.output])    {      [_session addOutput:self.output];    }    // 条码类型 AVMetadataObjectTypeQRCode    _output.metadataObjectTypes = [NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil];    dispatch_async(dispatch_get_main_queue(), ^{      //更新界面      _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];      _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;      _preview.frame = CGRectMake(0, 0, CGRectGetWidth(self.centerView.frame), CGRectGetHeight(self.centerView.frame));      [self.centerView.layer insertSublayer:self.preview atIndex:0];      [_session startRunning];    });  });}

在viewWillAppear和viewWillDisappear里对session做优化(timer是个扫描动画的计时器)

 - (void)viewWillAppear:(BOOL)animated {  [super viewWillAppear:animated];  if (_session && ![_session isRunning]) {    [_session startRunning];  }  timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(scanningAnimation) userInfo:nil repeats:YES];  [self setupCamera];} - (void)viewWillDisappear:(BOOL)animated {  [super viewWillDisappear:animated];  _count = 0;  [timer invalidate];  [self stopReading];}

处理扫描结果

 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {  NSString *stringValue;  if ([metadataObjects count] >0){    AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];    stringValue = metadataObject.stringValue;    NSLog(@"%@",stringValue);  }  [_session stopRunning];  [timer invalidate];  _count ++ ;  [self stopReading];  if (stringValue && _count == 1) {    //扫描完成  }}

用二维码扫描器扫描自己的二维码:

NSString *url = [NSURL URLWithString:@"html/judgement.html" relativeToURL:[ZXApiClient sharedClient].baseURL].absoluteString;  if ([stringValue hasPrefix:url]) {    //如果扫出来的url是自己的域名开头的,那么做如下的处理  }

最后附上自己完整的源码:

// Created by Ydw on 16/3/15. // Copyright © 2016年 IZHUO.NET. All rights reserved. //import “ViewController.h” import <AVFoundation/AVFoundation.h>@interface ViewController () { int number; NSTimer *timer; NSInteger _count; BOOL upOrdown; AVCaptureDevice *lightDevice; }@property (nonatomic,strong) UIView *centerView;//扫描的显示视图/** * 二维码扫描参数 */ @property (strong,nonatomic) AVCaptureDevice *device; @property (strong,nonatomic) AVCaptureDeviceInput *input; @property (strong,nonatomic) AVCaptureMetadataOutput *output; @property (strong,nonatomic) AVCaptureSession *session; @property (strong,nonatomic) AVCaptureVideoPreviewLayer *preview; @property (nonatomic,retain) UIImageView *imageView;//扫描线(void)setupCamera;(void)stopReading;@end @implementation ViewController- (void)viewWillAppear:(BOOL)animated {  [super viewWillAppear:animated];  if (_session && ![_session isRunning]) {    [_session startRunning];  }  timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(scanningAnimation) userInfo:nil repeats:YES];  [self setupCamera];}- (void)viewDidLoad {  [super viewDidLoad];  self.view.backgroundColor = [UIColor clearColor];  self.automaticallyAdjustsScrollViewInsets = NO;  _count = 0 ;  //初始化闪光灯设备  lightDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];  //扫描范围  _centerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame))];  _centerView.backgroundColor = [UIColor clearColor];  [self.view addSubview:_centerView];  //扫描的视图加载  UIView *scanningViewOne = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 120)];  scanningViewOne.backgroundColor= [[UIColor blackColor] colorWithAlphaComponent:0.4];  [self.centerView addSubview:scanningViewOne];  UIView *scanningViewTwo = [[UIView alloc]initWithFrame:CGRectMake(0, 120, (self.view.frame.size.width-300)/2, 300)];  scanningViewTwo.backgroundColor= [[UIColor blackColor] colorWithAlphaComponent:0.4];  [self.centerView addSubview:scanningViewTwo];  UIView *scanningViewThree = [[UIView alloc]initWithFrame:CGRectMake(CGRectGetWidth(self.view.frame)/2+150, 120, (self.view.frame.size.width-300)/2, 300)];  scanningViewThree.backgroundColor= [[UIColor blackColor] colorWithAlphaComponent:0.4];  [self.centerView addSubview:scanningViewThree];  UIView *scanningViewFour = [[UIView alloc]initWithFrame:CGRectMake(0, 420, self.view.frame.size.width,CGRectGetHeight(self.view.frame)- 420)];  scanningViewFour.backgroundColor= [[UIColor blackColor] colorWithAlphaComponent:0.4];  [self.centerView addSubview:scanningViewFour];  UILabel *labIntroudction= [[UILabel alloc] initWithFrame:CGRectMake(15, 430, self.view.frame.size.width - 30, 30)];  labIntroudction.backgroundColor = [UIColor clearColor];  labIntroudction.textAlignment = NSTextAlignmentCenter;  labIntroudction.textColor = [UIColor whiteColor];  labIntroudction.text = @"请将企业邀请码放入扫描框内";  [self.centerView addSubview:labIntroudction];  UIButton *openLight = [[UIButton alloc]initWithFrame:CGRectMake(CGRectGetWidth(self.view.frame)/2-25, 470, 50, 50)];  [openLight setImage:[UIImage imageNamed:@"灯泡"] forState:UIControlStateNormal];  [openLight setImage:[UIImage imageNamed:@"灯泡2"] forState:UIControlStateSelected];  [openLight addTarget:self action:@selector(openLightWay:) forControlEvents:UIControlEventTouchUpInside];  [self.centerView addSubview:openLight];  //扫描线  _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.frame)/2-110, 130, 220, 5)];  _imageView.image = [UIImage imageNamed:@"scanning@3x"];  [self.centerView addSubview:_imageView];}- (void)viewWillDisappear:(BOOL)animated {  _count= 0;  [timer invalidate];  [self stopReading];}pragma mark -- 设置参数- (void)setupCamera {  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];    _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];    _output = [[AVCaptureMetadataOutput alloc]init];    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];    _session = [[AVCaptureSession alloc]init];    [_session setSessionPreset:AVCaptureSessionPresetHigh];    if ([_session canAddInput:self.input])    {      [_session addInput:self.input];    }    if ([_session canAddOutput:self.output])    {      [_session addOutput:self.output];    }    // 条码类型 AVMetadataObjectTypeQRCode    _output.metadataObjectTypes = [NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil];    dispatch_async(dispatch_get_main_queue(), ^{      //更新界面      _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];      _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;      _preview.frame = CGRectMake(0, 0, CGRectGetWidth(self.centerView.frame), CGRectGetHeight(self.centerView.frame));      [self.centerView.layer insertSublayer:self.preview atIndex:0];      [_session startRunning];    });  });}//扫描动画- (void)scanningAnimation {  if (upOrdown == NO) {    number ++;    _imageView.frame = CGRectMake(CGRectGetWidth(self.view.frame)/2-115, 130+2*number, 230, 5);    if (2*number == 280) {      upOrdown = YES;    }  }  else {    number --;    _imageView.frame = CGRectMake(CGRectGetWidth(self.view.frame)/2-115, 130+2*number, 230, 5);    if (number == 0) {      upOrdown = NO;    }  }}- (void)stopReading {  [_session stopRunning];  _session = nil;  [_preview removeFromSuperlayer];  [timer invalidate];  timer = nil ;}-(void)openLightWay:(UIButton *)sender {  if (![lightDevice hasTorch]) {//判断是否有闪光灯    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"当前设备没有闪光灯,不能提供手电筒功能" message:nil preferredStyle:UIAlertControllerStyleAlert];    UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];    [alert addAction:sureAction];    [self presentViewController:alert animated:YES completion:nil];    return;  }  sender.selected = !sender.selected;  if (sender.selected == YES) {    [lightDevice lockForConfiguration:nil];    [lightDevice setTorchMode:AVCaptureTorchModeOn];    [lightDevice unlockForConfiguration];  }  else  {    [lightDevice lockForConfiguration:nil];    [lightDevice setTorchMode: AVCaptureTorchModeOff];    [lightDevice unlockForConfiguration];  }}pragma mark -- AVCaptureMetadataOutputObjectsDelegate- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {  NSString *stringValue;  if ([metadataObjects count] >0){    AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];    stringValue = metadataObject.stringValue;    NSLog(@"%@",stringValue);  }  [_session stopRunning];  [timer invalidate];  _count ++ ;  [self stopReading];  if (stringValue && _count == 1) {    //扫描完成  }}- (void)didReceiveMemoryWarning {  [super didReceiveMemoryWarning];  // Dispose of any resources that can be recreated.}@end

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表