首页 > 代码库 > iOS开发UI篇—实现一个简单的手势解锁应用(完善)

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 @end17 18 @interface YYLockView : UIView19 //代理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)viewDidLoad11 {12     [super viewDidLoad];13 }14 15 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd16 {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 *)event116 {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 *)touches147 {148     UITouch *touch=[touches anyObject];149     CGPoint point=[touch locationInView:touch.view];150     return point;151 }152 -(UIButton *)getCurrentBtnWithPoint:(CGPoint)point153 {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)rect164 {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         }else178         {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 @end17 18 @interface YYLockView : UIView19 //代理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 @end15 16 @implementation YYViewController17 18 - (void)viewDidLoad19 {20     [super viewDidLoad];21 }22 23 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd24 {25     NSLog(@"密码=%@",pwd);26 }27 @end