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

那么手势解锁功能是怎么是实现的呢,这里使用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. Lucene查询语法详解

    Lucene查询 Lucene查询语法以可读的方式书写,然后使用JavaCC进行词法转换,转换成机器可识别的查询. 下面着重介绍下Lucene支持的查询: Terms词语查询 词语搜索,支持 单词 和 ...

  2. 实现jquery.ajax及原生的XMLHttpRequest跨域调用WCF服务的方法

    关于ajax跨域调用WCF服务的方法很多,经过我反复的代码测试,认为如下方法是最为简便的,当然也不能说别人的方法是错误的,下面就来上代码,WCF服务定义还是延用上次的,如: namespace Wcf ...

  3. RDLC报表打印

    如果你的报表能正常显示,会看到RDLC工具条下的打印图标: 如果在客户端,第一次去点击此铵钮,如果当前操作者没有管理权限,会提示: Unable to load client print contro ...

  4. C# Winform MD5加密学习积累

    string password = txtPassword.Text.Trim(); byte[] result = Encoding.Default.GetBytes(password); MD5 ...

  5. c#使用WebClient登录网站抓取登录后的网页

    C#登录网站实际上就是模拟浏览器提交表单,然后记录浏览器响应返回的会话Cookie值,再次发送请求时带着这个会话cookie值去请求就可以实现模拟登录的效果了. 如下类CookieAwareWebCl ...

  6. 二路归并排序算法实现-完整C语言程序

    /*********************************************************************************************** 1.设 ...

  7. 修复一个吉日嘎拉MSSQL数据库版中的分页存储过程bug

    这个存储过程是3.7以来一直存在,并未针对MSSQL2005以上版本进行ROW_NUMBER() OVER升级,还是延续TOP的写法.这并非是我所谓的bug,我所说的bug是指执行了排序的字段,如果字 ...

  8. [范例] Firemonkey TForm 实现 OnMouseLeave 事件 (適用 Win & OS X)

    在 Firemonkey 的 TForm 并没有提供 OnMouseLeave 的事件,不过可以透过 OnMouseMove 来达到相同效果,请见代码: uses FMX.Consts; proced ...

  9. marquee标签滚动效果

    <marquee></marquee>标签,默认从最右侧往左滚动: direction:设置滚动的方向: height:设置标签高度, width:设置标签宽度: behavi ...

  10. jQUery操作checkbox

    1 2 3 <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script> <s ...