前言:看了几篇简书,九宫格密码解锁,看着不错,拿来学习一下。
一、实现效果
实现效果
二、手势解锁实现过程
分析:
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 |
<span class="hljs-preprocessor">#<span class="hljs-number">1.</span>监听手指在view上的移动,首先肯定需要自定义一个view,重写touch began,touch move等方法,</span> 当手指移动到圈上时,让其变亮。可以通过button按钮来实现。 <span class="hljs-preprocessor">#<span class="hljs-number">2.</span>界面搭建--【九宫格】代码的方式创建<span class="hljs-number">9</span>个按钮</span> <span class="hljs-number">1</span>).背景图片 <span class="hljs-number">2</span>).九个按钮 (把九个按钮作为一个整体,使用一个大的view来管理这些小的view,这些小的view就是<span class="hljs-number">9</span>个button)。 <span class="hljs-number">3</span>).新建一个类,对自定义的view进行管理,这个view是从storyboard创建出来的。 会调用aweakFrameNib方法和layoutSubviews方法,前者创造控件,后者,设置按钮frame。 <span class="hljs-number">4</span>).监听手指的移动。分析程序,应该监听手指的移动,而不是按钮的点击,当手指移动到按钮的范围内时,让按钮变亮。 (<span class="hljs-number">1</span>)重写touchesbegan...方法 <span class="hljs-number">1.</span>获取按下的点 <span class="hljs-number">2.</span>判断触摸的位置是否在按钮的范围内(使用<span class="hljs-keyword">for</span>循环) 提示: 一个判断点是否在指定范围内的方法——CGRectContainsPoint(,); (<span class="hljs-number">2</span>)重新touchesmoved...方法 说明:当手指移动到按钮上的时候,按钮变亮,因此需要重写touchesmoved方法。 <span class="hljs-number">1.</span>获取触摸的点 <span class="hljs-number">2.</span>判断触摸的点是否在按钮的范围内。 提示:可以把上面两个功能分别进行封装,在使用的时候直接调用即可。 <span class="hljs-preprocessor">#<span class="hljs-number">3</span>绘制线段</span> 思路:获取为选中状态的按钮,并把它们存到一个数组中,重写drawRect方法,从数组中取出所有的按钮,连接所有按钮的中点。 注意:数组中不能存空值,在存储之前需要先进行判断。 新的问题:已经被连过的按钮,不能再连线。(在存储按钮的时候判断,如果该按钮已经被连线,那么就不再添加到数组中)。 绘制线段 <span class="hljs-number">1.</span>获取上下文 <span class="hljs-number">2.</span>取出按钮(起点和终点) <span class="hljs-number">3.</span>渲染 |
如图所示:
①设置控制器view背景图片
[解析]:拖入图片素材,并设置控制器View的背景图片
设置控制器view背景图片
②自定义view并与控制器中新拖入的view进行关联
自定义view并与控制器中新拖入的view进行关联
③搭建UI
控件布局
设置触摸点,实现两个代理
④创建存储选中按钮的数组,并把选中按钮添加其中,画线重绘
- 解决问题:已经被连过的按钮,不能再连线。
[解析]:
1.由于每次画线的时候,我们都会调用touchbegin和touchmove方法,如果每次选中的按钮都在你触摸的范围内,都会添加到选中按钮的数组中。这样,就会造成重复添加按钮。即第二次,触摸已经选中的按钮,同样也在你触摸的范围内,这是同样也会添加到选中按钮的数组中。为了解决这个问题,我们可以在touchbegin和touchmove的判断中加一个条件 !btn.highlighted。如代码,意思是当你第二次,重复触摸同一个按钮时,如果他在你触摸的范围内且按钮的状态不是高亮状态,即向下执行。
1 |
if (CGRectContainsPoint(btn.frame, loc)&& !btn.highlighted) |
2.还有个问题就是,当你在连接按钮的过程中,在空白间隙停止触摸,这样,会产生多余的线。要解决这个问题,首先我们要声明一个多余线段的点CGpoint类型。其次,获取多余线段的点,多余线段的点就等于你所触摸获取的点,进行一下关联。然后,把多余的线段画出来。最后,在touchend这个方法内,也就是当触摸完毕之后,那个多余的点,就等于,选中按钮数组中最后一个按钮的中心点。在重绘一下,就OK。
避免重复添加按钮
多余线段的解决图1
多余线段的解决图2
多余线段的解决图3
④验证密码
[解析]:对与验证密码这块,基本的思路是根据选中按钮的tag值,来验证用户设置的手势密码是否与之对等。换句话来说,我们添加在自定义view的按钮,当每个按钮被触碰时,都会变成高亮状态,被添加到高亮状态的数组中。手势密码也就相当于(0~9)的密码串排序。手势密码验证是在,触摸结束后验证的。所以我们要想验证密码,必须在touchend方法里遍历高亮数组获取按钮的tag值。并存入可变字符串数组中,与自己设置的手势密码字符串进行对比。
设置按钮的tag值
密码验证正确:按钮高亮状态消失线消失
不正确:按钮红色,线消失:按钮状态消失
不正确:按钮红色,线消失:按钮状态消失
要想线消失
高亮状态消失线消失
- 代码展示:
-