手势解锁,这个小东西以前看着挺高大上的,但是实际上内容不是特别难,了解了就不深奥了,思路理一下
1、控制器中放一个imageView放背景图片,拖一个View放到屏幕中间用来放9个按钮;
2、自定义view类和控制器中的view绑定,所有内容均在自定义view中写;
3、封装一个方法,添加9个按钮,并且设置普通和选择状态的图片以及按钮的tag值,方便最后取路径,并且让按钮不能与用户交互,因为要整体把控手指的位置,不能用按钮的点击事件;
4、在解析xib时调用的方法 -(id)initWithCoder:(NSCoder *)sDecoder中或者在加载xib完成时调用的方法- (void)awakeFromNib中调用添加按钮的方法都可以;
5、设置按钮的位置,需要在- (void)layoutSubviews这个方法中设置,要用到九宫格算法;
6、设置完成之后按钮就可以显示了,接下来要处理手势,首先在手指点下的时候判断当前点是不是在按钮上面,如果在按钮上面要添加到事先准备好的按钮数组中,并且按钮的状态要是没被选中过的;
7、接下来是手指移动的时候,跟手指开始点的时候一样,但是要在最后调用setNeedsDisplay方法,不过要给准备好的当前位置赋值,进行重绘
8、最后是手指抬起来的时候,拼接按钮的tag值形成路径,调用按钮的setSeleed方法让按钮不被选中,清空按钮数组中得所有值并且重绘
9、最最重要的时绘图方法 :要先把按钮数组中的按钮连接起来,然后连接事先准备好的当前位置,设置自己喜欢的连线样式,最后渲染就可以了。
代码:
//
// CFLockView.m
// 手势解锁
//
// Created by chenfei on 15/6/19.
// Copyright (c) 2015年 chenfei. All rights reserved.
//
#import "CFLockView.h"
@interface CFLockView ()
@property (nonatomic, strong) NSMutableArray *btns;
@property (nonatomic, assign) CGPoint moveP;
@end
@implementation CFLockView
//懒加载
-(NSMutableArray *)btns{
if (_btns == nil) {
_btns = [NSMutableArray array];
}
return _btns;
}
// 加载xib完成的时候调用
- (void)awakeFromNib{
}
- (void)drawRect:(CGRect)rect {
if (!self.btns.count) return;
UIBezierPath *path = [UIBezierPath bezierPath];
// 把第一个作为起点
for (int i = 0; i < self.btns.count; i++) {
UIButton *btn = self.btns[i];
if (i == 0) {
[path moveToPoint:btn.center];
}else{
[path addLineToPoint:btn.center];
}
}
// 连接当前手指的位置
[path addLineToPoint:self.moveP];
[[UIColor greenColor] set];
path.lineWidth = 8;
path.lineJoinStyle = kCGLineCapRound;
// 渲染
[path stroke];
}
//解析xib时调用
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]) {
[self addBtns];
}
return self;
}
- (void)addBtns{
for (int i = 0; i < 9; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = i + 1;
[button setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
button.userInteractionEnabled = NO;
[self addSubview:button];
}
}
// 设置按钮frame
-(void)layoutSubviews{
[super layoutSubviews];
CGFloat col = 0;
CGFloat row = 0;
CGFloat btnW = 74;
CGFloat btnH = 74;
CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat totCol = 3;
CGFloat margin = (self.bounds.size.width - totCol * btnW) / (totCol + 1);
for (int i = 0; i < self.subviews.count; i++) {
UIButton *button = self.subviews[i];
col = i % 3;
row = i / 3;
btnX = margin + (margin + btnW) * col;
btnY = margin + (margin + btnH) * row;
button.frame = CGRectMake(btnX, btnY, btnW, btnH);
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint pos = [touch locationInView:self];
for (UIButton *btn in self.subviews) {
if (CGRectContainsPoint(btn.frame, pos) && btn.selected == NO) {
btn.selected = YES;
[self.btns addObject:btn];
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint pos = [touch locationInView:self];
self.moveP = pos;
// 修改小bug,让手指移动到按钮偏中心点才画,
// 只有移动到按钮中间的30 * 30的位置才画 注:按钮是74 * 74
CGFloat wh = 30;
for (UIButton *btn in self.subviews) {
CGFloat x = btn.center.x - wh * 0.5;
CGFloat y = btn.center.y - wh * 0.5;
CGRect frame = CGRectMake(x, y, wh, wh);
if (CGRectContainsPoint(frame, pos) && btn.selected == NO) {
btn.selected = YES;
[self.btns addObject:btn];
}
}
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSMutableString *str = [NSMutableString string];
for (UIButton *button in self.btns) {
[str appendFormat:@"%d",button.tag];
}
NSLog(@"%@", str);
[self.btns makeObjectsPerformSelector:@selector(setSelected:) withObject:NO];
[self.btns removeAllObjects];
[self setNeedsDisplay];
}
@end