#import "GestureView.h"
#define BUTTON_COUNT 9
@interface GestureView()
@property (nonatomic,strong) NSMutableArray *btns;
@property (nonatomic,strong) NSMutableArray *lineBtns;//存放需要连线的btn
@property (nonatomic,assign) CGPoint currentPoint;//手指最新的位置
@end
@implementation GestureView
-(NSMutableArray *)lineBtns
{
if (!_lineBtns) {
_lineBtns = [NSMutableArray array];
}
return _lineBtns;
}
-(NSMutableArray *)btns
{
if (!_btns) {
_btns = [NSMutableArray array];
for (int i = 0; i < BUTTON_COUNT; i ++)
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//设置tag 生成密码
btn.tag = i;
//关闭用户的交互
btn.userInteractionEnabled = NO;
//设置默认的图片样式
[btn setBackgroundImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
//设置高亮图片样式
[btn setBackgroundImage:[UIImage imageNamed:@""] forState:UIControlStateHighlighted];
//设置密码错误的图片样式
[btn setBackgroundImage:[UIImage imageNamed:@""] forState:UIControlStateSelected];
[self addSubview:btn];
[self.btns addObject:btn];
}
}
return _btns;
}
//点击这个view的时候调用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取触摸对象
UITouch *t = touches.anyObject;
//获取当前手势的位置
CGPoint p = [t locationInView:t.view];
for (int i = 0; i < self.btns.count; i ++)
{
//获取 btn
UIButton *btn = self.btns[i];
//判断手指的位置是不是在btn.frame的范围内
if (CGRectContainsPoint(btn.frame, p))
{
//如果是 设置这个按钮的高亮状态
btn.highlighted = YES;
//判断 当前的btn 是不是已经存在于需要划线的数组
if (![self.lineBtns containsObject:btn])
{
//如果不存在 再添加
//因为变成高亮 所以需要划线
[self.lineBtns addObject:btn];
}
}
}
}
//在这个view上移动的时候调用
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取触摸对象
UITouch *t = touches.anyObject;
//获取当前手势的位置
CGPoint p = [t locationInView:t.view];
//把最新的手指的位置 赋值给全局 属性 用来最后的连线
self.currentPoint = p;
for (int i = 0; i < self.btns.count; i ++)
{
//获取 btn
UIButton *btn = self.btns[i];
//判断手指的位置是不是在btn.frame的范围内
if (CGRectContainsPoint(btn.frame, p))
{
//如果是 设置这个按钮的高亮状态
btn.highlighted = YES;
//判断 当前的btn 是不是已经存在于需要划线的数组
if (![self.lineBtns containsObject:btn])
{
//如果不存在 再添加
//因为变成高亮 所以需要划线
[self.lineBtns addObject:btn];
}
}
}
//重绘
[self setNeedsDisplay];
}
//离开这个view的时候调用
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 把当前点的位置 修改为 画线数组的最后一个按钮的center
self.currentPoint = [[self.lineBtns lastObject] center];
//重绘
[self setNeedsDisplay];
//生成密码
NSString *pwd = @"";
//让所有需要连线的按钮都变成错误的样式 (变成选中状态)
for (int i = 0; i < self.lineBtns.count; i ++)
{
//获取btn
UIButton *btn = self.lineBtns[i];
btn.selected = YES;
btn.highlighted = NO;
// 密码
pwd = [pwd stringByAppendingString:[NSString stringWithFormat:@"%ld",btn.tag]];
}
//取消用户交互 解决错误以后还可以编辑的错误
self.userInteractionEnabled = NO;
//延时 取消
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//恢复到初试状态
[self clear];
//开启用户交互
self.userInteractionEnabled = YES;
});
}
//恢复到初试状态
- (void)clear
{
for (int i = 0; i < self.btns.count; i ++)
{
//获取btn
UIButton *btn = self.btns[i];
btn.highlighted = NO;
btn.selected = NO;
}
//清空所有的划线数组
[self.lineBtns removeAllObjects];
//重绘
[self setNeedsDisplay];
}
//划线
- (void)drawRect:(CGRect)rect
{
//创建一个路径
UIBezierPath *path = [UIBezierPath bezierPath];
for (int i = 0; i < self.lineBtns.count; i ++)
{
//获取btn
UIButton *btn = self.lineBtns[i];
if (i == 0){//如果 i== 0 设置初始位置
[path moveToPoint:btn.center];
}else{//如果 i!=0 连线
[path addLineToPoint:btn.center];
}
}
//判断 数组是不是有元素 如果有 再去连线到手指的位置
if (self.lineBtns.count)
{
//往手指的位置 连线
[path addLineToPoint:self.currentPoint];
}
//设置样式
[[UIColor colorWithRed:0 green:170/255.0 blue:1 alpha:1] set];
[path setLineWidth:2];
[path setLineCapStyle:kCGLineCapRound];
[path setLineJoinStyle:kCGLineJoinRound];
//渲染
[path stroke];
}
//计算九宫格布局
-(void)layoutSubviews
{
[super layoutSubviews];
for (int i = 0; i < self.btns.count; i ++)
{
//计算九宫格位置
CGFloat w = 74;
CGFloat h = w;
int colCount = 3;
CGFloat margin = (self.frame.size.width - 3 * w) / 4;
for (int i = 0; i < self.btns.count; i ++)
{
CGFloat x = (i % colCount) * (margin + w) + margin;
CGFloat y = (i / colCount) * (margin + w) + margin;
[self.btns[i] setFrame:CGRectMake(x, y, w, h)];
}
}
}
@end