手势解锁的实现


模仿支付宝手势解锁

思路总结:

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为正确密码




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值