//
// Created by wangtouwang on 15/4/7.
// Copyright (c) 2015年 wangtouwang. All rights reserved.
// #import <UIKit/UIKit.h> @class YYLockView;
@protocol YYLockViewDelegate <NSObject>
//自定义一个协议
//协议方法,把当前视图作为参数
-(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd;
@end @interface YYLockView : UIView //代理
@property(nonatomic,weak) IBOutlet id<YYLockViewDelegate>delegate; @end
//
// YYLockView.m
// Created by wangtouwang on 15/4/7.
// Copyright (c) 2015年 wangtouwang. All rights reserved.
// #import "YYLockView.h"
// 设置获取屏幕长宽全局变量
#define KSCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define KSCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define BUTTON_HEIGHT_MIDDLE_WIDTH_RADIO 1.22 @interface YYLockView ()
{
UIView *newView;
}
@property(nonatomic,strong)NSMutableArray *buttons;
@property(nonatomic,strong)NSMutableArray *includButtons; //定义一个属性,记录当前点
@property(nonatomic,assign)CGPoint currentPoint; @end @implementation YYLockView #pragma mark-懒加载
-(NSMutableArray *)buttons
{
if (_buttons==nil) {
_buttons=[NSMutableArray array];
}
return _buttons;
} #pragma mark-懒加载
-(NSMutableArray *)includButtons
{
if (_includButtons==nil) {
_includButtons=[NSMutableArray array];
}
return _includButtons;
} -(id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"断点 B 号 ");
if (self=[super initWithCoder:aDecoder]) {
[self setup];
}
return self;
} //界面搭建
- (id)initWithFrame:(CGRect)frame
{
NSLog(@"断点 1 号 ");
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
} //在界面上创建9个按钮
-(void)setup
{
// NSLog(@"断点 2 号 ");
// newView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
// newView.backgroundColor=[UIColor redColor];
// [self addSubview:newView];
//1.创建9个按钮
for (int i=; i<; i++) {
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置按钮的状态背景
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
//3.把按钮添加到视图中
[self addSubview:btn];
//将按钮添加到包含按钮数组中
[[self includButtons] addObject:btn];
//4.禁止按钮的点击事件
btn.userInteractionEnabled=NO;
//5.设置每个按钮的tag
btn.tag=i+;
}
} //4.设置按钮的frame
-(void)layoutSubviews
{
NSLog(@"断点顺序 3 号 ");
CGFloat inverst = KSCREEN_HEIGHT/4.5;
inverst=;
//4.1需要先调用父类的方法
[super layoutSubviews]; for (int i=; i<[self includButtons].count; i++) {
//4.2取出按钮
UIButton *btn=[self includButtons][i];
//4.3九宫格法计算每个按钮的frame
CGFloat row = i/;
CGFloat loc = i%;
// NSLog(@"ROW=%f LOC=%f",row,loc);
CGFloat btnW=;
CGFloat btnH=;
CGFloat padding=(self.frame.size.width-*btnW)/;
CGFloat btnX=padding+(btnW+padding)*loc;
CGFloat btnY=padding*BUTTON_HEIGHT_MIDDLE_WIDTH_RADIO+(btnW+padding)*row;
// NSLog(@"BTNX-%f BTNY=%f ",btnX,btnY);
btn.frame=CGRectMake(btnX, btnY+inverst, btnW, btnH);
}
} //重写drawrect:方法
-(void)drawRect:(CGRect)rect
{
NSLog(@"断点顺序 4 号 "); //获取上下文
CGContextRef ctx=UIGraphicsGetCurrentContext(); //在每次绘制前,清空上下文
CGContextClearRect(ctx, rect); //填充画布颜色
[[self renderImageWithColor:[UIColor grayColor] inSize:CGSizeMake(KSCREEN_WIDTH, KSCREEN_HEIGHT)] drawInRect:CGRectMake(, , KSCREEN_WIDTH, KSCREEN_HEIGHT)];//在坐标中画出图片 //绘图(线段)
for (int i=; i<self.buttons.count; i++) {
UIButton *btn=self.buttons[i];
if (==i) {
//设置起点(注意连接的是中点)
// CGContextMoveToPoint(ctx, btn.frame.origin.x, btn.frame.origin.y);
CGContextMoveToPoint(ctx, btn.center.x, btn.center.y);
}else
{
// CGContextAddLineToPoint(ctx, btn.frame.origin.x, btn.frame.origin.y);
CGContextAddLineToPoint(ctx, btn.center.x, btn.center.y);
}
} //当所有按钮的中点都连接好之后,再连接手指当前的位置
//判断数组中是否有按钮,只有有按钮的时候才绘制
if (self.buttons.count !=) {
CGContextAddLineToPoint(ctx, self.currentPoint.x, self.currentPoint.y);
} //渲染
//设置线条的属性
CGContextSetLineWidth(ctx, );
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetRGBStrokeColor(ctx, /255.0, /255.0, /255.0, ); CGContextStrokePath(ctx); } //填充画布颜色
- (UIImage *)renderImageWithColor:(UIColor *)color inSize:(CGSize)size
{
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect); UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); return image;
} //5.监听手指的移动
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"断点 E 号 ");
CGPoint starPoint=[self getCurrentPoint:touches];
UIButton *btn=[self getCurrentBtnWithPoint:starPoint]; if (btn && btn.selected != YES) {
btn.selected=YES;
[self.buttons addObject:btn];
}
// [self setNeedsDisplay];
} -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"断点 F 号 ");
CGPoint movePoint=[self getCurrentPoint:touches];
UIButton *btn=[self getCurrentBtnWithPoint:movePoint];
//存储按钮
//已经连过的按钮,不可再连
if (btn && btn.selected != YES) {
//设置按钮的选中状态
btn.selected=YES;
//把按钮添加到数组中
[self.buttons addObject:btn];
}
//记录当前点(不在按钮的范围内)
self.currentPoint=movePoint;
//通知view重新绘制
[self setNeedsDisplay];
} //手指离开的时候清除线条
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"断点 G 号 ");
//取出用户输入的密码
//创建一个可变的字符串,用来保存用户密码
NSMutableString *result=[NSMutableString string];
for (UIButton *btn in self.buttons) {
[result appendFormat:@"%lu",btn.tag];
}
NSLog(@"用户输入的密码为:%@",result);
//通知代理,告知用户输入的密码
if ([self.delegate respondsToSelector:@selector(LockViewDidClick:andPwd:)]) {
[self.delegate LockViewDidClick:self andPwd:result];
} //重置按钮的状态
// for (UIButton *btn in self.buttons) {
// btn.selected=NO;
//// [btn setSelected:NO];
// } //调用该方法,它就会让数组中的每一个元素都调用setSelected:方法,并给每一个元素传递一个NO参数
[self.buttons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];
//清空数组
[self.buttons removeAllObjects];
[self setNeedsDisplay]; //清空当前点
self.currentPoint=CGPointZero;
} //对功能点进行封装
-(CGPoint)getCurrentPoint:(NSSet *)touches
{
NSLog(@"断点 H 号 ");
UITouch *touch=[touches anyObject];
CGPoint point=[touch locationInView:touch.view];
return point;
}
-(UIButton *)getCurrentBtnWithPoint:(CGPoint)point
{
NSLog(@"断点 J 号 ");
for (int i=;i<_includButtons.count;i++) {
UIButton *btn =_includButtons[i];
if (CGRectContainsPoint(btn.frame, point)) {
return btn;
}
}
return Nil;
} @end
 

(转 部分修改) IOS 手势密码(简单版)的更多相关文章

  1. swift 实现iOS手势密码、指纹密码、faceID

    本博客包含了如何实现iOS手势密码.指纹密码.faceID全步骤,包括了完整的代码. 先附上demo地址https://github.com/Liuyubao/LYBTouchID,支持swift3. ...

  2. 28.【转载】挖洞技巧:APP手势密码绕过思路总结

    说到APP手势密码绕过的问题,大家可能有些从来没接触过,或者接触过,但是思路也就停留在那几个点上,这里我总结了我这1年来白帽子生涯当中所挖掘的关于这方面的思路,有些是网上已经有的,有些是我自己不断摸索 ...

  3. APP手势密码绕过

    之前写的文章收到了很多的好评,主要就是帮助到了大家学习到了新的思路.自从发布了第一篇文章,我就开始筹备第二篇文章了,最终打算在07v8首发,这篇文章我可以保障大家能够学习到很多思路.之前想准备例子视频 ...

  4. iOS 九宫格手势密码

    代码地址如下:http://www.demodashi.com/demo/11490.html 一.准备工作 需要准备什么环境 xcode,iOS8+ 本例子实现什么功能 主要实现手势密码设置,验证 ...

  5. 下载文件时-修改文件名字 Redis在Windows中安装方法 SVN安装和使用(简单版) WinForm-SQL查询避免UI卡死 Asp.Net MVC Https设置

    下载文件时-修改文件名字   1后台代码 /// <summary> /// 文件下载2 /// </summary> /// <param name="Fil ...

  6. iOS 教你如何实现手势密码

    本次讲的手势密码,是在九个按键上实现的,这里讲的是手势密码的基本实现和效果 同样先上效果图 其实就是对画图功能的一个实现,再加上手势操作结合起来 屏幕宽度高度,方便下面操作,不做解释 #define ...

  7. 手把手教你修改iOS版QQ的运动步数

    手把手教你修改iOS版QQ的运动步数 现在很多软件都加上了运动模块,比如QQ和微信,而且还有排行榜,可以和好友比较谁的运动步数多,任何东西只要添加了比较功能,就变得不一样了.今天教大家用代码去修改QQ ...

  8. IOS 学习笔记 2015-04-15 手势密码(原)

    // // WPSignPasswordView.h // 网投网 // // Created by wangtouwang on 15/4/9. // Copyright (c) 2015年 wan ...

  9. 精通iOS开发(第5版)

    <精通iOS开发(第5版)> 基本信息 原书名:Beginning ios 6 development:exploring the ios sdk 作者: (美)David Mark   ...

随机推荐

  1. Worker、Task、Executor三者之间的关系

  2. A Tour of Go Variables with initializers

    A var declaration can include initializers, one per variable. If an initializer is present, the type ...

  3. 数据库ACID和CAP理论

    1.ACID是RDBMS的理论基石:      A原子(Atomiclty )事务原子性:      C一致(Consistency)插入一张表数据,会 影响其它(索引/其它表)等一致.      I ...

  4. rcp(插件开发)The type XXX cannot be resolved. It is indirectly referenced from required .class files解决办法

    如果你在使用插件开发时遇到这个问题: The type org.eclipse.core.resources.IFile cannot be resolved. It is indirectly re ...

  5. (一)Memcached初学教程之安装服务篇(Windows下)

    1.下载Memcached的Windows服务安装程序(备注:memcached官网:http://memcached.org/ ,没有提供windows下的安装包,只有UNIX下的安装包,我们这里用 ...

  6. Robot Framework自动化测试(三)--- 封装系统关键字

    之前对robotframework-ride了解的不多,后来知道了引入Selenium2Lirary库后可以做web UI自动化测试,但发现和python没啥关系,今天学习了封装系统关键字算是和pyt ...

  7. linux命令之cat

    转自:http://www.cnblogs.com/peida/archive/2012/10/30/2746968.html cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容, ...

  8. [微信小程序] 终于可以愉快的使用 async/await 啦

    [小程序] 终于可以愉快的使用 async/await 啦 这篇文章主要是想说一下 怎么在微信小程序中使用async/await从而逃离回调地狱 背景 最近一直在搞微信小程序 用的语言是TypeScr ...

  9. [转帖] 安装Eclipse插件长时间卡在 calculating requirements and dependencies

    把"Contact all update sites during install to find required software"前面的勾去掉,然后点击下一步,这样之后问题迎 ...

  10. 【剪枝】HDU 1010——tempter of the bone

    来源:点击打开链接 看上去数据规模很小,但是必须要剪枝,否则直接爆TLE. 通过这个题可以练习奇偶剪枝. 另外:还有一个优化方式,如果所有步数走完了门还没关,则直接返回结果"NO" ...