当前位置:首页 > 通信资讯 > 正文

ios 手势解锁(Ios手势操作)

本文主要介绍通过手势识别实现手势解锁功能,这个方法被广泛用于手机解锁,密码验证,快捷支付等功能实现。事例效果如下所示。

ios 手势解锁(Ios手势操作)

首先,我们先分析功能的实现过程,首先我们需要先看大致的实现过程:

1.加载九宫格页面

2.实现按钮被点击及滑动过程中按钮状态的改变

3.实现滑动过程中的连线

4.绘制完毕后判定密码是否正确,

5.密码判定后实现跳转。

下面我们就来用代码实现上述五个过程。

1.加载九宫格界面

1.1九宫格内控件的分布 3*3 ,我们可以自定义view(包含3*3个按钮),添加到viewcontroller上。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //添加view中子控件 -(void)awakefromnib { // 创建按钮 for (int i=0; i<9; i++) { self.linecolor=[uicolor bluecolor]; uibutton *btn=[uibutton buttonwithtype:uibuttontypecustom]; btn.userinteractionenabled=no; // 设置按钮属性 [btn setbackgroundimage:[uiimage imagenamed:@"gesture_node_normal"] forstate:uicontrolstatenormal]; [btn setbackgroundimage:[uiimage imagenamed:@"gesture_node_highlighted"] forstate:uicontrolstatehighlighted ]; [btn setbackgroundimage:[uiimage imagenamed:@"gesture_node_error"] forstate:uicontrolstatedisabled]; [self addsubview:btn]; } } //布局view子控件 -(void)layoutsubviews { [super layoutsubviews]; cgfloat width=74; cgfloat height=74; cgfloat margin=(self.bounds.size.width-3*width)/2; // 遍历设置9个button的frame [self.subviews enumerateobjectsusingblock:^(__kindof uiview * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { // 通过tag设置按钮的索引标识 obj.tag=idx; int row=(int)idx/3; int col=idx%3; obj.frame=cgrectmake(col*(margin + width), row*(margin +height), width, height); }]; }

1.2将定义好的view通过xib添加到viewcontroller上

首先,定义一个blockview(九宫格view)的类方法,

?
1 2 3 4 5 // 加载xib文件 +(instancetype)lockview { return [[[nsbundle mainbundle]loadnibnamed:@"myblockview" owner:nil options:nil]lastobject]; }

然后加载到控制器上。

?
1 2 3 4 5 6 // 设置控制器view的背景图片 self.view.backgroundcolor=[uicolor colorwithpatternimage:[uiimage imagenamed:@"bg"]]; myblockview *blockview=[myblockview lockview]; blockview.center=self.view.center; // 将blockview添加到viewcontroller上 [self.view addsubview:blockview];

2.实现按钮被点击及滑动过程中按钮状态的改变

2.1定义数组类型的成员属性,用来装被点击的按钮

?
1 2 3 4 5 6 7 8 9 @property(nonatomic,strong)nsmutablearray *btnarr; //懒加载 -(nsmutablearray *)btnarr { if (_btnarr==nil) { _btnarr=[nsmutablearray array]; } return _btnarr; }

2.2创建路径,绘制图形

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #pragma mark----绘制图形 -(void)drawrect:(cgrect)rect { if (self.btnarr.count==0 ) { return; } // 创建路径 uibezierpath *path=[uibezierpath bezierpath]; // 遍历所有按钮进行绘制 [self.btnarr enumerateobjectsusingblock:^(__kindof uibutton * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { // 第一个按钮,中心点就是起点 if (idx==0) { [path movetopoint:obj.center]; }else { [path addlinetopoint:obj.center]; } }]; [path addlinetopoint:self.currentpoint]; // 设置路径属性 path.linewidth=10; path.linecapstyle=kcglinecapround; path.linejoinstyle=kcglinejoinround; [self.linecolor setstroke]; // 渲染 [path stroke]; }

2.3开始触摸

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #pragma mark-----开始触摸 -(void)touchesbegan:(nsset<uitouch *> *)touches withevent:(uievent *)event { // 获取触摸对象 uitouch *touch=touches.anyobject; // 获取触摸点 cgpoint loc=[touch locationinview:self]; // 遍历按钮,判定触摸点是否在按钮上 [self.subviews enumerateobjectsusingblock:^(__kindof uibutton * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { bool iscontains=cgrectcontainspoint(obj.frame, loc); // 如果在按钮上,将当前按钮保存在数组中,并改变按钮状态 if (iscontains&&obj.highlighted==no) { [self.btnarr addobject:obj]; obj.highlighted=yes; }else { obj.highlighted=no; } }]; }

2.4滑动过程中,重绘

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #pragma mark----开始滑动 -(void)touchesmoved:(nsset<uitouch *> *)touches withevent:(uievent *)event { // 获取触摸对象 uitouch *touch=touches.anyobject; // 获取触摸点 cgpoint loc=[touch locationinview:self]; self.currentpoint=loc; // 遍历按钮,如果按钮在滑动路径上,就改变按钮状态 [self.subviews enumerateobjectsusingblock:^(__kindof uibutton * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { bool iscontains=cgrectcontainspoint(obj.frame, loc); if (iscontains&&obj.highlighted==no) { [self.btnarr addobject:obj]; obj.highlighted=yes; } }]; // 重绘 [self setneedsdisplay]; }

3.实现滑动过程中的连线和4.绘制完毕后判定密码是否正确

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #pragma mark----停止滑动结束 -(void)touchesended:(nsset<uitouch *> *)touches withevent:(uievent *)event { // 定义最后一个按钮 uibutton *lastbtn=[self.btnarr lastobject]; // 将最后一个按钮中心点定义为相对滑动的当前点 self.currentpoint=lastbtn.center; // 重绘 [self setneedsdisplay]; // 判定密码 self.password=[nsmutablestring string]; [self.btnarr enumerateobjectsusingblock:^( uibutton * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { [self.password appendformat:@"%@",@(obj.tag)]; }]; nslog(@"%@",self.password); bool isok; if ([self.delegate respondstoselector:@selector(blockview:finishedwithpassword:)]) { isok= [self.delegate blockview:self finishedwithpassword:self.password]; } if (isok) { [self.btnarr enumerateobjectsusingblock:^(uibutton* _nonnull obj, nsuinteger idx, bool * _nonnull stop) { obj.highlighted=no; }]; [self.btnarr removeallobjects]; [self setneedsdisplay]; nslog(@"密码正确"); }else { nslog(@"密码错误"); } }

注意:我们在密码判定过程中是通过根据先前布局按钮的时候定义的按钮tag值进行字符串拼接,密码传值是通过代理实现。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 #import <uikit/uikit.h> @class myblockview; //声明代理 @protocol myblockviewdelegate <nsobject> @optional //代理方法 -(bool) blockview:(myblockview *)blockview finishedwithpassword:(nsstring *)password; @end @interface myblockview : uiview +(instancetype)lockview; //设置代理成员属性 @property(nonatomic,weak)id<myblockviewdelegate>delegate; @end

5.密码判定后实现跳转。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 else { // 关闭用户交互 self.userinteractionenabled=no; [self.btnarr enumerateobjectsusingblock:^(uibutton * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { self.linecolor=[uicolor redcolor]; obj.highlighted=no; obj.enabled=no; [self setneedsdisplay]; dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(1.0 * nsec_per_sec)), dispatch_get_main_queue(), ^{ // 回复按钮状态 [self.btnarr enumerateobjectsusingblock:^(uibutton * _nonnull obj, nsuinteger idx, bool * _nonnull stop) { obj.enabled=yes; }]; // 恢复线条的颜色 self.linecolor=[uicolor bluecolor]; [self.btnarr removeallobjects]; [self setneedsdisplay]; }); }]; nslog(@"密码错误"); } self.userinteractionenabled=yes; }

代理判定密码并实现跳转

?
1 2 3 4 5 6 7 8 9 10 11 12 13 -(bool)blockview:(myblockview *)blockview finishedwithpassword:(nsstring *)password { if ([password isequaltostring:@"012"]) { uiviewcontroller *two=[uiviewcontroller new]; two.view.backgroundcolor=[uicolor greencolor]; [self.navigationcontroller pushviewcontroller:two animated:yes]; return yes; } else{ return no; } }

最后设置控制器navigationbar属性

?
1 2 3 4 [self.navigationcontroller.navigationbar setbackgroundcolor:[uicolor redcolor]]; [ self.navigationcontroller.navigationbar settitletextattributes:@{ nsforegroundcolorattributename :[uicolor whitecolor] }];

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

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。