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篇—实现一个简单的手势解锁应用(完善),,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。