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

“摇一摇”功能的实现:

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

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

(0)

相关推荐

  • iOS仿微信摇一摇动画效果加震动音效实例

    众所周知, 微信中的摇一摇功能: 搜索人/歌曲/电视,同样在一些其他类APP中也有一个摇一摇签到, 摇一摇随机选号等功能,下面以微信摇一摇功能来介绍实现原理. 对于摇一摇功能, 在iOS中系统默认为我们提供了摇一摇的功能检测API. iOS 中既然已经提供了接口, 我们直接调用就好了. #import <QuartzCore/QuartzCore.h> #import <AudioToolbox/AudioToolbox.h> 实现原理 1. 监听摇一摇方法 // 摇一摇开始 -

  • IOS 实现摇一摇的操作

    要实现摇一摇的功能,类似于微信的摇一摇 方法1:通过分析加速计数据来判断是否进行了摇一摇操作(比较复杂) 方法2:iOS自带的Shake监控API(非常简单) 本文介绍方法2: 判断摇一摇的步骤: 1)检测到开始摇动 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{ //检测到后可做一些处理 } 2)摇一摇被取消或中断 - (void)motionCancelled:(UIEventSubtype)mot

  • iOS实现微信朋友圈与摇一摇功能

    本Demo为练手小项目,主要是熟悉目前主流APP的架构模式.此项目中采用MVC设计模式,纯代码和少许XIB方式实现.主要实现了朋友圈功能和摇一摇功能. 预览效果: 主要重点 1.整体架构 利用UITabBarController和UINavigationController配合实现.其中要注意定义基类,方便整体上的管理,例如对UINavigationController头部的颜色,字体和渲染颜色等设置.以及对UITabBarController的底部的渲染等. [self.navigationB

  • Vue PC端实现扫码登录功能示例代码

    目录 需求描述 思路解析 前端功能实现 如何控制二维码的时效性? 前端如何获取服务器二维码的状态? 本篇文章给大家带来了关于Vue的相关知识,其中主要介绍了在PC端实现扫码的原理是什么?怎么生成二维码图片?怎么用Vue实现前端扫码登录?感兴趣的朋友,下面一起来看一下吧,希望对大家有帮助. 需求描述 目前大多数PC端应用都有配套的移动端APP,如微信,淘宝等,通过使用手机APP上的扫一扫功能去扫页面二维码图片进行登录,使得用户登录操作更方便,安全,快捷. 思路解析 PC 扫码原理? 扫码登录功能涉

  • 基于 Swoole 的微信扫码登录功能实现代码

    随着微信的普及,扫码登录方式越来越被现在的应用所使用.它因为不用去记住密码,只要有微信号即可方便快捷登录.微信的开放平台原生就有支持扫码登录的功能,不过大部分人还是在用公众平台,所以扫码登录只能自行实现.这里基于微信公众平台的带参数临时二维码,并且结合 Swoole 的 WebSocket 服务实现扫码登录.大体流程如下: 客户端打开登录界面,连接到 WebSocket 服务 WebScoket 服务生成带参数二维码返回给客户端 用户扫描展示的带参数二维码 微信服务器回调扫码事件并通知开发者服务

  • SpringBoot实现扫码登录的示例代码

    目录 一.首先咱们需要一张表 二.角色都有哪些 三.接口都需要哪些? 四.步骤 五.疯狂贴代码 SpringBoot中操作WebSocket 最近有个项目涉及到websocket实现扫码登录,看到一篇不错的技术文,分享一下. 一.首先咱们需要一张表 这表是干啥的呢?就是记录一下谁扫码了.谁登录了. User_Token表 字段如下: uuid : 用于确保唯一性 userId :谁登录的 loginTime :登录时间 createTime :创建时间 用于判断是否过期 state:是否二维码失

  • 基于Java实现扫码登录的示例代码

    目录 基本介绍 原理解析 1. 身份认证机制 2. 流程概述 代码实现 1. 环境准备 2. 主要依赖 3. 生成二维码 4. 扫描二维码 5. 确认登录 6. PC 端轮询 7. 拦截器配置 效果演示 1. 工具准备 2. 数据准备 3. 扫码登录流程展示 结语 基本介绍 相信大家对二维码都不陌生,生活中到处充斥着扫码登录的场景,如登录网页版微信.支付宝等.最近学习了一下扫码登录的原理,感觉蛮有趣的,于是自己实现了一个简易版扫码登录的 Demo,以此记录一下学习过程. 实际上是面试的时候被问到

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

    "摇一摇"功能的实现: iPhone对 "摇一摇"有很好的支持,总体说来就两步: 在视图控制器中打开接受"摇一摇"的开关; - (void)viewDidLoad { // 设置允许摇一摇功能 [UIApplication sharedApplication].applicationSupportsShakeToEdit = YES; // 并让自己成为第一响应者 [self becomeFirstResponder]; } 在"摇一摇

  • iOS如何跳转到App Store下载评分页面示例代码

    前言 目前很多应用是要求点击事件直接跳转到App Store,最近工作中就遇到了一个跳转 App Store 评分或者下载更新的功能,网上查到很多跳转方法,这里记录一下,下面话不多说了,来一起看看详细的介绍吧. 主要跳转方法有两种 使用官方 StoreKit.framework 框架 应用间跳转直接跳到 App Store 应用,并携带自己 App 的 AppID. 使用官方框架 苹果提供了StoreKit.framework框架,工程中可以导入这个框架的主头文件 #import <StoreK

  • Python实现扫码工具的示例代码

    二维码作为一种信息传递的工具,在当今社会发挥了重要作用.从手机用户登录到手机支付,生活的各个角落都能看到二维码的存在.那你知道二维码是怎么解析的吗?有想过自己实现一个扫码工具吗?如果想的话就继续看下去吧! 一.案例分析 我们先思考一下,实现扫码工具需要写什么操作.在扫码过程中我们需要打开摄像头,如何由手机或者电脑识别二维码.所以我们要实现两个关键的步骤:调用摄像头.识别二维码. 这两个操作分别对应了两个模块,它们就是opencv和pyzbar,其中opencv是英特尔的计算机视觉处理模块,而py

  • iOS仿微信摇一摇功能

    iOS仿照微信摇一摇功能实现 一.描述 需要做一个界面,仿照微信摇一摇,获取接口进行签到功能. 首先明确以下几点: 1.需要震动. 2.需要声音.(准备好mp3音效) 二.直接贴代码 / Created by 石雄伟 on 16/7/29. // Copyright © 2016年 石雄伟. All rights reserved. // #import "SignBoardViewController.h" #import <AVFoundation/AVFoundation.

  • iOS使用CoreMotion实现摇一摇功能

    现在网上介绍的iOS摇一摇功能,基本是以借助系统的ShakeToEdit功能来实现,什么是ShakeToEdit?看下图应该就能懂: 怎么实现?请看以下代码: //ViewController 加入以下两方法 -(BOOL)canBecomeFirstResponder { //让当前controller可以成为firstResponder,这很重要 return YES; } -(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEven

随机推荐