模仿支付宝手势解锁
思路总结:
1>touchBegin (获取当前的触摸点,如果当前的触摸点在按钮的范围内,并且该按钮的状态不是高亮,就将该按钮添加到数组中)
2>touchMove(将当前的触摸点赋值给标记属性【self setNeedsDisplay】)
3>touchEnd(如果当前点不在按钮范围内,就将当前点赋值为数组中的最后一个点)
4>drawRect(遍历数组中的按钮,将第一个按钮设置为起点,连线,连接当前点)
主要代码:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch * touch = touches.anyObject;
// 触摸点
CGPoint loc = [touch locationInView:touch.view];
[self getPointWithLoc:loc];
// [self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch * touch = touches.anyObject;
// 触摸点
CGPoint loc = [touch locationInView:touch.view];
self.currentPoint = loc;
[self getPointWithLoc:loc];
[self setNeedsDisplay];
}
// 获取当前点
- (void)getPointWithLoc:(CGPoint)loc
{
CGFloat width = 26;
// 遍历数组
for (UIButton * btn in self.subviews) {
CGFloat btnX = btn.center.x - width * 0.5;
CGFloat btnY = btn.center.y - width * 0.5;
// 判断触摸点是不是在按钮的frame里 在的话,显示高亮
if (CGRectContainsPoint(CGRectMake(btnX, btnY, width, width), loc) && btn.highlighted == NO) {
btn.highlighted = YES;
// 将选中的按钮添加到数组中
[self.selBtnArray addObject:btn];
}
}
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 将当前触摸点设置为最后一个点
self.currentPoint = [[self.selBtnArray lastObject] center];
// 拼接密码
NSMutableString * passWord = [NSMutableString string];
for (UIButton * btn in self.selBtnArray) {
[passWord appendFormat:@"%@",@(btn.tag)];
}
BOOL isTure = NO;
// // 验证密码
if ([self.delegate respondsToSelector:@selector(unLockView:withPassWord:)]) {
isTure = [self.delegate unLockView:self withPassWord:passWord];
}
if (isTure) { // 密码为真
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 将按钮的状态改变
for (UIButton * btn in self.selBtnArray) {
btn.highlighted = NO;
}
// 将选中的按钮清除
[self.selBtnArray removeAllObjects];
[self setNeedsDisplay];
});
}else{// 密码为假
self.userInteractionEnabled = NO;
for (UIButton * btn in self.selBtnArray) {
btn.enabled = NO;
btn.highlighted = NO;
}
_lineColor = [UIColor redColor];
[self setNeedsDisplay];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.userInteractionEnabled = YES;
for (UIButton * btn in self.selBtnArray) {
btn.enabled = YES;
}
// 将选中的按钮清除
[self.selBtnArray removeAllObjects];
[self setNeedsDisplay];
self.lineColor = WTColor;
});
}
}
- (void)drawRect:(CGRect)rect
{
// 重写drawRect方法
if (self.selBtnArray.count == 0) return;
UIBezierPath * path = [UIBezierPath bezierPath];
// 遍历选中的数组
for(int i = 0 ;i < self.selBtnArray.count; i ++ ){
UIButton * btn = self.selBtnArray[i];
if (0 == i) {
// 第一个按钮设置为起点
[path moveToPoint:btn.center];
}
// 连线
[path addLineToPoint:btn.center];
}
[path addLineToPoint:_currentPoint];
// 线条颜色
[self.lineColor set];
// 线条的宽度
path.lineWidth = 13;
// 线条样式
path.lineJoinStyle = kCGLineCapRound;
path.lineCapStyle = kCGLineCapRound;
// 渲染
[path stroke];
}
012为正确密码