这次支付宝手机客户端升级,把手势解锁那个功能去掉了,引起很多人的抱怨,觉得少了手势解锁的保护,个人信息容易泄漏了。。。

那么手势解锁功能是怎么是实现的呢,这里使用Quart2D来简单模拟一下,

先看下截图效果:

         

按钮的有两个背景图片,一个默认样式,一个用于选中样式:

  

代码实现:

自定义view, 用来绘制所有路径,自定义view名称为:GestureLockView

GestureLockView.h文件:

#import <UIKit/UIKit.h>

@interface GestureLockView : UIView

@end

GestureLockView.m文件代码:

 //  手势解锁

 #import "GestureLockView.h"

 @interface GestureLockView()

 @property (nonatomic, retain) NSMutableArray *selectBtns;
@property (nonatomic, assign) CGPoint moveP; //移动的点 @end @implementation GestureLockView - (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]){
[self addBtns];
NSLog(@"initWithFrame: %s", __func__);
}
return self;
} //解析xib的时候调用
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]){
NSLog(@"initWithCoder: %s", __func__);
[self addBtns];
}
return self;
} //添加子按钮
- (void)addBtns{
for (int i = ; i < ; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
[btn setUserInteractionEnabled:NO]; //设置不能和用户进行交互
[btn setTag:i + ]; //设置标识
[self addSubview:btn];
}
} - (NSMutableArray *)selectBtns{
if (_selectBtns == nil){
_selectBtns = [[NSMutableArray alloc] init];
}
return _selectBtns;
} //触摸开始
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"触摸开始..."); self.moveP = [self getPoint:touches];
UIButton *btn = [self getBtn:self.moveP]; if (btn != nil){
[self.selectBtns addObject:btn];
btn.selected = YES;
}
} //触摸移动, 设置被选中的按钮
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
//NSLog(@"触摸移动");
self.moveP = [self getPoint:touches];
UIButton *btn = [self getBtn:self.moveP]; if (btn != nil && btn.selected == NO){
[self.selectBtns addObject:btn];
btn.selected = YES;
} [self setNeedsDisplay]; //从新绘制
} //触摸结束,一切归空
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSMutableString *str = [[NSMutableString alloc] init];
for (UIButton * btn in self.selectBtns) {
[str appendFormat:@"%i", btn.tag];
btn.selected = NO;
} self.moveP = CGPointZero;
[self setNeedsDisplay];
[self.selectBtns removeAllObjects]; // UILabel *lbl = [[UILabel alloc] init];
// lbl.text = [NSString stringWithFormat:@"密码是:%@", str];
// lbl.frame = CGRectMake(80, 150, 200, 30);
// [lbl setBackgroundColor:[UIColor whiteColor]];
// [lbl setTextAlignment:NSTextAlignmentCenter];
// [self addSubview:lbl];
//
// [UIView animateWithDuration:5.0 animations:^{
// lbl.alpha = 0.1;
// } completion:^(BOOL finished) {
// [lbl removeFromSuperview];
// }]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"设置结果为" message:str delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alert show];
} //监听触摸移动,获取触摸坐标
- (CGPoint)getPoint: (NSSet *)touches{
UITouch *touch = [touches anyObject]; //获取当前接触点
return [touch locationInView:self]; //获取当前触点在父对象中的位置
} //根据坐标获取按钮对象
- (UIButton *)getBtn: (CGPoint)point{
for (UIButton * btn in self.subviews) {
if (CGRectContainsPoint(btn.frame, point)){
return btn;
}
}
return nil;
} //布局子控件的坐标位置
- (void)layoutSubviews{
CGFloat width = ;
CGFloat height = width;
CGFloat cols = ;
CGFloat rows = cols;
CGFloat margin = ([UIScreen mainScreen].bounds.size.width - width * cols) / (cols + ); for (int i = ; i < rows; i++) {
for (int j = ; j < cols; j++) {
CGFloat x = j * (width + margin) + margin;
CGFloat y = i * (height + margin) + margin;
UIButton *btn = (UIButton *)[self.subviews objectAtIndex: (i * rows) + j];
btn.frame = CGRectMake(x, y, width, height);
}
}
} //
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
//从新绘制
- (void)drawRect:(CGRect)rect {
//1、获取当前上下文
CGContextRef ctr = UIGraphicsGetCurrentContext();
//2、绘制路径
UIBezierPath *path = [UIBezierPath bezierPath];
CGContextSetLineWidth(ctr, ); //设置线段宽度
CGContextSetLineJoin(ctr, kCGLineJoinRound); //设置转折点
[[UIColor whiteColor] set]; //设置路径颜色 [path moveToPoint:self.moveP]; for (int i = ; i < self.selectBtns.count; i++) {
UIButton *btn = (UIButton *)[self.selectBtns objectAtIndex:i];
CGPoint point = btn.center; if (i == ){
[path moveToPoint:point];
}
else{
[path addLineToPoint:point];
}
} if (!CGPointEqualToPoint(self.moveP, CGPointZero)){
[path addLineToPoint:self.moveP]; //重点路径
}
//3、把路径添加到上下文中
CGContextAddPath(ctr, path.CGPath); //4、渲染
CGContextStrokePath(ctr);
} @end

自定义控制器来展示自定义手势解锁view

GestureLockViewController.h :

#import <UIKit/UIKit.h>

@interface GestureLockViewController : UIViewController

@end

GestureLockViewController.m文件代码:

 #import "GestureLockViewController.h"
#import "GestureLockView.h" @interface GestureLockViewController () @end @implementation GestureLockViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view setBackgroundColor:[UIColor whiteColor]]; //返回按钮
UIButton *preBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[preBtn setFrame:CGRectMake(, , , )];
[preBtn setBackgroundColor:[UIColor purpleColor]];
[preBtn setTitle:@"返回" forState:UIControlStateNormal];
[preBtn addTarget:self action:@selector(prePage) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:preBtn]; //增加view
CGSize size = [UIScreen mainScreen].bounds.size;
GestureLockView *view = [[GestureLockView alloc] initWithFrame:CGRectMake(, , size.width, size.width + )];
[view setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:view];
} - (void)prePage{
[self dismissViewControllerAnimated:YES completion:nil];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} /*
#pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/ @end

Quartz2D复习(二) --- 手势解锁的更多相关文章

  1. AJ学IOS(35)UI之Quartz2D仿真支付宝手势解锁_代理获得密码。

    AJ分享,必须精品 效果: 实现步骤 其实这个实现起来不难 第一步先放好主要的UI,一张背景图和一个View 第二部就是把9个button放到view中,设置好按钮的默认和选中图片. 注意:创建时候的 ...

  2. 2016-1-10 手势解锁demo的实现

    一:实现自定义view,在.h,.m文件中代码如下: #import <UIKit/UIKit.h> @class ZLLockView; @protocol ZLLockViewDele ...

  3. ReactNative手势解锁(react-native-ok-gesture-password)

    在大前端的趋势之下,我也慢慢开始从事React Native相关的开发.但是奈何React Native生态相对于Android来说还是太小了.许多开源的库早早就已经不再维护.之前项目中需要用到手势解 ...

  4. iOS-高仿支付宝手势解锁(九宫格)

    概述 高仿支付宝手势解锁, 通过手势枚举去实现手势密码相对应操作. 详细 代码下载:http://www.demodashi.com/demo/10706.html 基上篇[TouchID 指纹解锁] ...

  5. SJGestureUnlock快速集成手势解锁

    前言:如果页面显示不完整或图片看不了还请移步:简书 SJGestureUnlock.h 常用自定义属性 @interface SJGestureUnlock : UIView @property (n ...

  6. Quartz2D复习(三) --- 涂鸦

    和上一篇手势解锁不一样,手势解锁只画了一条路径,从触摸开始-->触摸移动-->触摸结束 ,然后路径完成了,渲染出来就是手势解锁了: 这次涂鸦想做到的效果是可以画很多次线段或弧,每次又可以设 ...

  7. HTML5实现屏幕手势解锁

    HTML5实现屏幕手势解锁(转载) https://github.com/lvming6816077/H5lockHow to use? <script type="text/java ...

  8. iOS--开发之手势解锁

    本文主要介绍通过手势识别实现手势解锁功能,这个方法被广泛用于手机解锁,密码验证,快捷支付等功能实现.事例效果如下所示. 首先,我们先分析功能的实现过程,首先我们需要先看大致的实现过程: 1.加载九宫格 ...

  9. iOS绘制手势解锁密码

    手势解锁这个功能其实已经用的越来越少了.但是郁闷不知道我公司为什么每次做一个app都要把手势解锁加上.....于是就自己研究了一下手势解锁页面的实现.. 要想实现这个页面,先说说需要掌握哪些: UIP ...

随机推荐

  1. URL格式

    URL由三部分组成:资源类型.存放资源的主机域名.资源文件名. URL的一般语法格式为: (带方括号[]的为可选项): protocol :// hostname[:port] / path / [; ...

  2. plsql导入excel时报错:ORA-01036: 非法变量名/编号

    导入oracle数据,选择工具->odbc导入->Excel 然后关于日期的插入出错,修改后如下:

  3. Redis Lua脚本原理

    2.6版本之后支持嵌入Lua脚本,客户端使用Lua脚本,直接在服务器端原子的执行多条命令 Lua脚本执行过程 创建并修改Lua环境 1 创建基础Lua环境 2 载入函数库 3 创建全局表格Lua 4 ...

  4. APP数据接口开发的一些经验

    刚接到这样的任务时,没有感觉到任何压力,不就是给移动端应用提供数据吗?那边发来参数,这边处理数据,返回JSON.做网站开发时经常使用ajax请求后台数据,不就是这么回事吗.于是,在确认完需求后就开始干 ...

  5. Moon.Orm 5.0(MQL版)分页功能的设计(求指教,邀请您的加入)

    一.分页的分类及分析 1)分页的前置条件: 查询的目标条件.第几页.总页数(本质上由查询条件决定).每页条数.请求地址.按照什么字段怎样排序 2)目标结果: 数据列表,List<T>返回 ...

  6. 30天C#基础巩固----Lambda表达式

         这几天有点不在状态,每一次自己很想认真的学习,写点东西的时候都会被各种小事情耽误,执行力太差.所以自己反思了下最近的学习情况,对于基础的知识,可以从书中和视频中学习到,自己还是需要注意下关于 ...

  7. C# 在异步中使用HttpWebRequest出现的“正在终止线程”错误的解决方案

    最近做接口对接,因需求变化需要用到异步推送信息,就利用委托做了异步. 程序运行过程中时不时出现“正在终止线程”的错误信息,导致两边订单信息不一致,代码如下: byte[] byteData = Enc ...

  8. SUI分页组件和avalon搞定ajax无刷新分页

    <div ms-controller="main"> <h2 class="pagination-centered">{{ title ...

  9. 孙鑫MFC学习笔记14:网络编程

    1.OSI 2.TCP/IP与OSI对应关系 3.Socket 4.客户机/服务器模式 5.Windows Sockets 6.套接字类型 7.面向连接的socket编程 8.面向无连接的socket ...

  10. Raising Error Conditions with MySQL SIGNAL / RESIGNAL Statements

    http://www.mysqltutorial.org/mysql-signal-resignal/ Summary: in this tutorial, you will learn how to ...