iOS开发UI篇—实现一个简单的手势解锁应用(完善)

iOS开发UI篇—实现一个简单的手势解锁应用(完善)

一、需要实现的效果

  

二、应用完善

1.绘制不处于按钮范围内的连线

2.解决bug(完善)

bug1:如果在began方法中通知view绘图,那么会产生bug。因为,当前点没有清空,在手指移开之后要清空当前点。可以在绘制前进行判断,如果当前点是(0,0)那么就不划线。或者在began方法中不进行重绘。

bug2:无限菊花。自定义view的背景色为默认的(黑色),只要重写了drawrect方法,view默认的背景颜色就是黑色的,因为上下文默认的颜色是黑色的。会有缓存,出现无限菊花。可以通过在每次绘制前对上下文进行清空。

调整后的效果:

注意点:当自定义view的背景颜色为默认的时候,会有缓存。

bug3:没有当前点(没有起点)。判断数组中是否有按钮,如果有按钮,那么就有起点不会报错。

三、获取用户输入的手势密码

实现效果:

获取用户的手势(密码)

思路:当用户手指离开屏幕的时候,获取用户输入的密码(手势)。需要每个按钮表示一个唯一的数字,可以考虑使用tag值,作为按钮的唯一标识。创建一个可变的字符串,通过一个循环,把数组中的每个按钮的tag值添加到可变字符串中。

提示:考虑把获取用户输入密码环节进行封装。比较用户密码是否正确应该在控制器的业务逻辑中进行处理。

思路:自定义一个协议,设置代理,获取用户输入的密码后,告诉代理用户输入的密码。

设置代理

代码:

在自定义view的头文件YYLockView.h中自定义一个协议。

 1 //
 2 //  YYLockView.h
 3 //  01-手势解锁(基本)
 4 //
 5 //  Created by apple on 14-6-18.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8
 9 #import <UIKit/UIKit.h>
10
11 @class YYLockView;
12 @protocol YYLockViewDelegate <NSObject>
13 //自定义一个协议
14 //协议方法,把当前视图作为参数
15 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd;
16 @end
17
18 @interface YYLockView : UIView
19 //代理
20 @property(nonatomic,weak) IBOutlet id<YYLockViewDelegate>delegate;
21 @end

在Touchesended方法中通知代理

 1     //取出用户输入的密码
 2     //创建一个可变的字符串,用来保存用户密码
 3     NSMutableString *result=[NSMutableString string];
 4     for (UIButton *btn in self.buttons) {
 5         [result appendFormat:@"%d",btn.tag];
 6     }
 7     NSLog(@"用户输入的密码为:%@",result);
 8     //通知代理,告知用户输入的密码
 9     if ([self.delegate respondsToSelector:@selector(LockViewDidClick:andPwd:)]) {
10         [self.delegate LockViewDidClick:self andPwd:result];
11     }

在主控制器中实现协议中的方法

 1 #import "YYViewController.h"
 2 #import "YYLockView.h"
 3
 4 @interface YYViewController ()<YYLockViewDelegate>
 5
 6 @end
 7
 8 @implementation YYViewController
 9
10 - (void)viewDidLoad
11 {
12     [super viewDidLoad];
13 }
14
15 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd
16 {
17     NSLog(@"密码=%@",pwd);
18 }
19 @end

四、附录

完整代码:

自定义的view中,YYLockView.m文件

  1 //
  2 //  YYLockView.m
  3 //  01-手势解锁(基本)
  4 //
  5 //  Created by apple on 14-6-18.
  6 //  Copyright (c) 2014年 itcase. All rights reserved.
  7 //
  8
  9 #import "YYLockView.h"
 10
 11 @interface YYLockView ()
 12 @property(nonatomic,strong)NSMutableArray *buttons;
 13 //定义一个属性,记录当前点
 14 @property(nonatomic,assign)CGPoint currentPoint;
 15 @end
 16 @implementation YYLockView
 17
 18 #pragma mark-懒加载
 19 -(NSMutableArray *)buttons
 20 {
 21     if (_buttons==nil) {
 22         _buttons=[NSMutableArray array];
 23     }
 24     return _buttons;
 25 }
 26
 27 //界面搭建
 28 - (id)initWithFrame:(CGRect)frame
 29 {
 30     self = [super initWithFrame:frame];
 31     if (self) {
 32         [self setup];
 33     }
 34     return self;
 35 }
 36
 37 -(id)initWithCoder:(NSCoder *)aDecoder
 38 {
 39     if (self=[super initWithCoder:aDecoder]) {
 40         [self setup];
 41     }
 42     return self;
 43 }
 44 //在界面上创建9个按钮
 45 -(void)setup
 46 {
 47     //1.创建9个按钮
 48     for (int i=0; i<9; i++) {
 49         UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
 50         //2.设置按钮的状态背景
 51         [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
 52         [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
 53         //3.把按钮添加到视图中
 54         [self  addSubview:btn];
 55         //4.禁止按钮的点击事件
 56         btn.userInteractionEnabled=NO;
 57         //5.设置每个按钮的tag
 58         btn.tag=i;
 59     }
 60 }
 61
 62 //4.设置按钮的frame
 63 -(void)layoutSubviews
 64 {
 65     //4.1需要先调用父类的方法
 66     [super layoutSubviews];
 67     for (int i=0; i<self.subviews.count; i++) {
 68         //4.2取出按钮
 69         UIButton *btn=self.subviews[i];
 70
 71     //4.3九宫格法计算每个按钮的frame
 72         CGFloat row = i/3;
 73         CGFloat loc   = i%3;
 74         CGFloat btnW=74;
 75         CGFloat btnH=74;
 76         CGFloat padding=(self.frame.size.width-3*btnW)/4;
 77         CGFloat btnX=padding+(btnW+padding)*loc;
 78         CGFloat btnY=padding+(btnW+padding)*row;
 79         btn.frame=CGRectMake(btnX, btnY, btnW, btnH);
 80     }
 81 }
 82
 83 //5.监听手指的移动
 84 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 85 {
 86     CGPoint starPoint=[self getCurrentPoint:touches];
 87     UIButton *btn=[self getCurrentBtnWithPoint:starPoint];
 88
 89     if (btn && btn.selected != YES) {
 90         btn.selected=YES;
 91         [self.buttons addObject:btn];
 92     }
 93 //    [self setNeedsDisplay];
 94 }
 95
 96 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 97 {
 98     CGPoint movePoint=[self getCurrentPoint:touches];
 99     UIButton *btn=[self getCurrentBtnWithPoint:movePoint];
100     //存储按钮
101     //已经连过的按钮,不可再连
102     if (btn && btn.selected != YES) {
103         //设置按钮的选中状态
104         btn.selected=YES;
105         //把按钮添加到数组中
106         [self.buttons addObject:btn];
107     }
108     //记录当前点(不在按钮的范围内)
109     self.currentPoint=movePoint;
110     //通知view重新绘制
111     [self setNeedsDisplay];
112 }
113
114 //手指离开的时候清除线条
115 -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
116 {
117     //取出用户输入的密码
118     //创建一个可变的字符串,用来保存用户密码
119     NSMutableString *result=[NSMutableString string];
120     for (UIButton *btn in self.buttons) {
121         [result appendFormat:@"%d",btn.tag];
122     }
123     NSLog(@"用户输入的密码为:%@",result);
124     //通知代理,告知用户输入的密码
125     if ([self.delegate respondsToSelector:@selector(LockViewDidClick:andPwd:)]) {
126         [self.delegate LockViewDidClick:self andPwd:result];
127     }
128
129     //重置按钮的状态
130 //    for (UIButton *btn in self.buttons) {
131 //        btn.selected=NO;
132 ////        [btn setSelected:NO];
133 //    }
134
135     //调用该方法,它就会让数组中的每一个元素都调用setSelected:方法,并给每一个元素传递一个NO参数
136     [self.buttons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];
137     //清空数组
138     [self.buttons removeAllObjects];
139     [self setNeedsDisplay];
140
141     //清空当前点
142     self.currentPoint=CGPointZero;
143 }
144
145 //对功能点进行封装
146 -(CGPoint)getCurrentPoint:(NSSet *)touches
147 {
148     UITouch *touch=[touches anyObject];
149     CGPoint point=[touch locationInView:touch.view];
150     return point;
151 }
152 -(UIButton *)getCurrentBtnWithPoint:(CGPoint)point
153 {
154     for (UIButton *btn in self.subviews) {
155         if (CGRectContainsPoint(btn.frame, point)) {
156             return btn;
157         }
158     }
159     return Nil;
160 }
161
162 //重写drawrect:方法
163 -(void)drawRect:(CGRect)rect
164 {
165     //获取上下文
166     CGContextRef ctx=UIGraphicsGetCurrentContext();
167     //在每次绘制前,清空上下文
168     CGContextClearRect(ctx, rect);
169
170     //绘图(线段)
171     for (int i=0; i<self.buttons.count; i++) {
172         UIButton *btn=self.buttons[i];
173         if (0==i) {
174             //设置起点(注意连接的是中点)
175 //            CGContextMoveToPoint(ctx, btn.frame.origin.x, btn.frame.origin.y);
176             CGContextMoveToPoint(ctx, btn.center.x, btn.center.y);
177         }else
178         {
179 //            CGContextAddLineToPoint(ctx, btn.frame.origin.x, btn.frame.origin.y);
180             CGContextAddLineToPoint(ctx, btn.center.x, btn.center.y);
181         }
182     }
183
184     //当所有按钮的中点都连接好之后,再连接手指当前的位置
185     //判断数组中是否有按钮,只有有按钮的时候才绘制
186     if (self.buttons.count !=0) {
187         CGContextAddLineToPoint(ctx, self.currentPoint.x, self.currentPoint.y);
188     }
189
190     //渲染
191     //设置线条的属性
192     CGContextSetLineWidth(ctx, 10);
193     CGContextSetLineJoin(ctx, kCGLineJoinRound);
194     CGContextSetLineCap(ctx, kCGLineCapRound);
195     CGContextSetRGBStrokeColor(ctx, 20/255.0, 107/255.0, 153/255.0, 1);
196     CGContextStrokePath(ctx);
197 }
198 @end

YYLockView.h文件代码

 1 //
 2 //  YYLockView.h
 3 //  01-手势解锁(基本)
 4 //
 5 //  Created by apple on 14-6-18.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8
 9 #import <UIKit/UIKit.h>
10
11 @class YYLockView;
12 @protocol YYLockViewDelegate <NSObject>
13 //自定义一个协议
14 //协议方法,把当前视图作为参数
15 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd;
16 @end
17
18 @interface YYLockView : UIView
19 //代理
20 @property(nonatomic,weak) IBOutlet id<YYLockViewDelegate>delegate;
21 @end

主控制器文件

 1 //
 2 //  YYViewController.m
 3 //  01-手势解锁(基本)
 4 //
 5 //  Created by apple on 14-6-18.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8
 9 #import "YYViewController.h"
10 #import "YYLockView.h"
11
12 @interface YYViewController ()<YYLockViewDelegate>
13
14 @end
15
16 @implementation YYViewController
17
18 - (void)viewDidLoad
19 {
20     [super viewDidLoad];
21 }
22
23 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd
24 {
25     NSLog(@"密码=%@",pwd);
26 }
27 @end

iOS开发UI篇—实现一个简单的手势解锁应用(完善)

时间: 2024-10-23 12:10:17

iOS开发UI篇—实现一个简单的手势解锁应用(完善)的相关文章

iOS开发UI篇—实现一个简单的手势解锁应用(基本)

iOS开发UI篇—实现一个简单的手势解锁应用(基本) 一.实现效果 实现效果图: 二.手势解锁应用分析 1.监听手指在view上的移动,首先肯定需要自定义一个view,重写touch began,touch move等方法,当手指移动到圈上时,让其变亮.可以通过button按钮来实现. 2.界面搭建 背景图片(给控制器的view添加一个imageview,设置属性背景图片) 九个按钮(把九个按钮作为一个整体,使用一个大的view来管理这些小的view,这些小的view就是9个button.如果使

iOS开发UI篇—xib的简单使用

iOS开发UI篇—xib的简单使用 一.简单介绍 xib和storyboard的比较,一个轻量级一个重量级. 共同点: 都用来描述软件界面 都用Interface Builder工具来编辑 不同点: Xib是轻量级的,用来描述局部的UI界面 Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系 二.xib的简单使用 1.建立xib文件 建立的xib文件命名为appxib.xib 2.对xib进行设置 根据程序的需要,这里把view调整为自由布局 建立vie

文顶顶 iOS开发UI篇—xib的简单使用

iOS开发UI篇—xib的简单使用 一.简单介绍 xib和storyboard的比较,一个轻量级一个重量级. 共同点: 都用来描述软件界面 都用Interface Builder工具来编辑 不同点: Xib是轻量级的,用来描述局部的UI界面 Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系 二.xib的简单使用 1.建立xib文件 建立的xib文件命名为appxib.xib 2.对xib进行设置 根据程序的需要,这里把view调整为自由布局 建立vie

iOS开发UI篇—实现一个私人通讯录小应用(一)

iOS开发UI篇—实现一个私人通讯录小应用(一) 一.该部分主要完成内容 1.界面搭建                        2.功能说明 (1).只有当账号和密码输入框都有值的时候,登录按钮才能交互 (2).当取消勾选记住密码后,自动登录按钮也随之取消:当勾选了自动登录按钮时,记住密码按钮也一同勾选. (3).点击登陆后,弹出蒙版,界面不可交互,程序能够简单判断账号和密码是否正确,如果不正确则给出相应的提示,如果正确则跳转到联系人列表界面. 二.实现过程和代码 项目文件结构图和界面搭建

iOS开发UI篇—实现一个私人通讯录小应用(一) - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3773603.html iOS开发UI篇—实现一个私人通讯录小应用(一) 一.该部分主要完成内容 1.界面搭建                        2.功能说明 (1).只有当账号和密码输入框都有值的时候,登录按钮才能交互 (2).当取消勾选记住密码后,自动登录按钮也随之取消:当勾选了自动登录按钮时,记住密码按钮也一同勾选. (3).点击登陆后,弹出蒙版,界面不可交互,程序能够简单判断账号和密码是否正确

iOS开发UI篇—实现一个私人通讯录小应用(二)

iOS开发UI篇—实现一个私人通讯录小应用(二) 一.实现功能说明 (1)点击注销按钮,弹出一个对话框,点击确定后移除当前栈顶的控制器,返回开始界面,点击取消,不做任何操作. 注意:注销按钮的单击事件已经进行了连线.实现-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex需要遵守UIActionSheetDelegate协议. 1 //注销按钮 2 - (IBActi

iOS开发UI篇—实现一个私人通讯录小应用(二) - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3777087.html iOS开发UI篇—实现一个私人通讯录小应用(二) 一.实现功能说明 (1)点击注销按钮,弹出一个对话框,点击确定后移除当前栈顶的控制器,返回开始界面,点击取消,不做任何操作. 注意: 注销按钮的单击事件已经进行了连线.实现-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)butto

iOS开发UI篇—实现一个私人通讯录小应用【转】

转一篇学习segue不错的教程 一.该部分主要完成内容 1.界面搭建                        2.功能说明 (1).只有当账号和密码输入框都有值的时候,登录按钮才能交互 (2).当取消勾选记住密码后,自动登录按钮也随之取消:当勾选了自动登录按钮时,记住密码按钮也一同勾选. (3).点击登陆后,弹出蒙版,界面不可交互,程序能够简单判断账号和密码是否正确,如果不正确则给出相应的提示,如果正确则跳转到联系人列表界面. 二.实现过程和代码 项目文件结构图和界面搭建 实现代码: YY

iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序

iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序 一.plist文件和项目结构图 说明:这是一个嵌套模型的示例 二.代码示例: YYcarsgroup.h文件代码: // // YYcarsgroup.h // 07-汽车展示(高级) // // Created by apple on 14-5-28. // Copyright (c) 2014年 itcase. All rights reserved. // #import <Foundation/Foundation.h> @