iOS实现手势密码功能
程序员文章站
2023-12-20 16:59:34
手势密码实现
手势密码 一般常常用于金融项目,做的是安全相关的业务。具体实现如下思路,我把它分为view层和逻辑层。我将数据层合并到view层中了,最好是加上数据层用于处...
手势密码实现
手势密码 一般常常用于金融项目,做的是安全相关的业务。具体实现如下思路,我把它分为view层和逻辑层。我将数据层合并到view层中了,最好是加上数据层用于处理加密的密码和密码的存储
view层
view层主要处理,包括(九个按钮)touchesbegan,touchesmoved,touchesended,点与点之间画线,手指滑动画线,画线主要是在drawrect中重绘,提到这里必须不能忘记setneedsdisplay这个方法。还要记录经过的按钮btnsarray(存放按钮的数组),这个 可以和相关的具体值做映射,也可以直接设置btn 的tag,还要添加完成绘画的回调。提供给逻辑层去处理。
逻辑层
用于处理完成交互后的业务,包括(请求接口,异常逻辑显示,等等)
具体的demo点这里
具体的code:
view.h
// // yhgesturepasswordview.h // 手势密码 // // created by mrlee on 2017/3/5. // copyright © 2017年 mrlee. all rights reserved. // typedef enum { gesturesetpassword, //设置手势密码 gestureresultpassword //已有手势密码教验 } passwordstate; //设置密码的3种状态 typedef enum { fristpwd, //第一次设置密码 pwdnovalue, //二次设置密码不一致 setpwdsuccess, //设置密码成功 other }setpwdstate; #import <uikit/uikit.h> @interface yhgesturepasswordview : uiview /** btn图片*/ @property (nonatomic,strong)uiimage *btnimage; ///选中的图片 @property (nonatomic,strong)uiimage *btnselectimage; ///划线颜色 @property (nonatomic,strong)uicolor *linecolor; /** 解锁手势完成之后判断结果时调用的block */ @property (nonatomic,copy)bool (^sendreaultdata)(nsstring *str); //设置手势密码 @property(nonatomic,copy)void(^setpwdblock)(setpwdstate pwdstate); // init -(instancetype)initwithframe:(cgrect)frame withstate:(passwordstate)state; @end
view.m
// // yhgesturepasswordview.m // 手势密码 // // created by mrlee on 2017/3/5. // copyright © 2017年 mrlee. all rights reserved. // #define screen_width [uiscreen mainscreen].bounds.size.width #define screen_height [uiscreen mainscreen].bounds.size.height #import "yhcustombutton.h" #import "yhgesturepasswordview.h" #import <commoncrypto/commondigest.h> @interface yhgesturepasswordview(){ /** 判断是当设置密码用,还是解锁密码用*/ passwordstate amode; } /** 所有的按钮集合*/ @property (nonatomic,strong)nsmutablearray * allbtnsarray; /** 解锁时手指经过的所有的btn集合*/ @property (nonatomic,strong)nsmutablearray * btnsarray; /** 手指当前的触摸位置*/ @property (nonatomic,assign)cgpoint currentpoint; @end @implementation yhgesturepasswordview -(instancetype)initwithframe:(cgrect)frame withstate:(passwordstate)state{ self = [super initwithframe:frame]; if (self) { self.backgroundcolor = [uicolor clearcolor]; amode = state; for (int i = 0; i<9; i++) { yhcustombutton *btn = [[yhcustombutton alloc]init]; [btn settag:i]; btn.userinteractionenabled = no; if (self.linecolor == nil) { self.linecolor = [uicolor greencolor]; } [self addsubview:btn]; } } return self; } -(void)drawrect:(cgrect)rect{ // 每次调用这个方法的时候如果背景颜色是default会产生缓存,如果设置了颜色之后就没有缓存,绘制之前需要清除缓存 cgcontextref ctx = uigraphicsgetcurrentcontext(); cgcontextclearrect(ctx, rect);//清空上下文 for (int i = 0; i<self.btnsarray.count; i++) { uibutton *btn = self.btnsarray[i]; if (i == 0) { cgcontextmovetopoint(ctx, btn.center.x, btn.center.y); }else{ cgcontextaddlinetopoint(ctx, btn.center.x, btn.center.y); } } if (!cgpointequaltopoint(self.currentpoint, cgpointzero)) {//如果起点不是cgpointzero的话才来划线 cgcontextaddlinetopoint(ctx, self.currentpoint.x, self.currentpoint.y); } cgcontextsetlinewidth(ctx, 12); cgcontextsetlinecap(ctx, kcglinecapround); cgcontextsetlinejoin(ctx, kcglinejoinround); [self.linecolor set]; cgcontextstrokepath(ctx); } -(void)layoutsubviews{ [self.allbtnsarray removeallobjects]; for (int index =0; index<self.subviews.count; index ++) { if ([self.subviews[index] iskindofclass:[yhcustombutton class]]) { [self.allbtnsarray addobject:self.subviews[index]]; } } // button 绘制九宫格 [self drawui]; } #pragma mark private method -(void)drawui{ for (int index = 0; index<self.allbtnsarray.count; index ++) { //拿到每个btn uibutton *btn = self.subviews[index]; //设置frame cgfloat btnw = 74; cgfloat btnh = 74; cgfloat margin = (screen_width - (btnw *3))/4; //x = 间距 + 列号*(间距+btnw) cgfloat btnx = margin + (index % 3)*(margin + btnw); cgfloat btny = margin + (index / 3)*(margin + btnh); btn.frame = cgrectmake(btnx, btny, btnw, btnh); } } //设置密码 -(setpwdstate)pwdvalue:(nsstring *)str{ if ([[nsuserdefaults standarduserdefaults] objectforkey:@"pwdvalue"] == nil) { //第一次设置 [[nsuserdefaults standarduserdefaults] setvalue:str forkey:@"pwdvalue"]; return fristpwd; } if ([str isequaltostring: [[nsuserdefaults standarduserdefaults]objectforkey:@"pwdvalue"]]) { //设置成功 return setpwdsuccess; } if (![str isequaltostring: [[nsuserdefaults standarduserdefaults]objectforkey:@"pwdvalue"]]) { //二次设置不一样 return pwdnovalue; } return other; } //清空 -(void)clear{ [self.btnsarray removeallobjects]; self.currentpoint = cgpointzero; [self setneedsdisplay]; self.linecolor = [uicolor greencolor]; self.userinteractionenabled = yes; } //获取触摸的点 -(cgpoint)getcurrenttouch:(nsset<uitouch*> *)touches{ uitouch *touch = [touches anyobject]; cgpoint point = [touch locationinview:touch.view]; return point; } -(uibutton *)getcurrentbtnwithpoint:(cgpoint) currentpoint{ for (uibutton *btn in self.subviews) { if (cgrectcontainspoint(btn.frame, currentpoint)) { return btn; } } return nil; } -(void)touchesbegan:(nsset<uitouch *> *)touches withevent:(uievent *)event{ cgpoint point = [self getcurrenttouch:touches]; uibutton *btn = [self getcurrentbtnwithpoint:point]; if (btn && btn.selected != yes) { btn.selected = yes; [self.btnsarray addobject:btn]; nslog(@" array is value %@",self.btnsarray); } } -(void)touchesmoved:(nsset<uitouch *> *)touches withevent:(uievent *)event{ cgpoint movepoint = [self getcurrenttouch:touches]; uibutton *btn = [self getcurrentbtnwithpoint:movepoint]; if (btn && btn.selected !=yes) { btn.selected = yes; [self.btnsarray addobject:btn]; nslog(@"btn is value %@",self.btnsarray); } self.currentpoint = movepoint; [self setneedsdisplay]; } -(void)touchesended:(nsset<uitouch *> *)touches withevent:(uievent *)event{ for (uibutton *btn in self.btnsarray) { [btn setselected:no]; } nsmutablestring *result = [nsmutablestring string]; for (uibutton *btn in self.btnsarray) { [result appendstring: [nsstring stringwithformat:@"%ld",(long)btn.tag]]; } switch (amode) { case gesturesetpassword:{ //设置手势密码 self.setpwdblock([self pwdvalue:result]); } break; case gestureresultpassword :{ //获取手势密码结果 if (self.sendreaultdata) { if (self.sendreaultdata(result) == yes) { nslog(@"success"); [self clear]; }else{ nslog(@"手势有误"); } } } break; default: break; } //返回结果 [self clear]; } #pragma mark 延时加载 -(nsmutablearray *)btnsarray{ if (_btnsarray == nil) { _btnsarray = [nsmutablearray array]; } return _btnsarray; } -(nsmutablearray *)allbtnsarray{ if (_allbtnsarray == nil) { _allbtnsarray = [nsmutablearray array]; } return _allbtnsarray; } @end
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。