iOS手势密码浅析

手势密码的使用:
手势密码构造的核心思想是绘图,主要问题为一下四个问题
一:移动起始点到移动末端的处理(如何绘图)
二:非绘图点为起始点如何处理
三:是否过关键绘图点(Button or ImageView)
四:如何进行密码的保存

下面我们带着这四个问题开始进行处理手势解锁

touch事件的处理

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint touchPoint;
    UITouch *touch = [touches anyObject];
    [touchesArray removeAllObjects];
    [touchedArray removeAllObjects];
//    开始滑动,清空临时密码(上次滑动产生的临时密码)
    [touchBeginDelegate gestureTouchBegin];
    success=1;
    if (touch) {
//        touch的坐标点
        touchPoint = [touch locationInView:self];
        for (int i=0; i<buttonArray.count; i++) {
//            获取关键绘图点(密码点)
            GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]);
            [buttonTemp setSuccess:YES];
            [buttonTemp setSelected:NO];
//            判断起始点是不是在密码点中
            if (CGRectContainsPoint(buttonTemp.frame,touchPoint)) {
                CGRect frameTemp = buttonTemp.frame;
//                button的中心点
                CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/2,frameTemp.origin.y+frameTemp.size.height/2);
                NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",point.x],@"x",[NSString stringWithFormat:@"%f",point.y],@"y", nil];
//                添加触动点
                [touchesArray addObject:dict];
//                把触动点做为起始点
                lineStartPoint = touchPoint;
            }
            [buttonTemp setNeedsDisplay];
        }

        [self setNeedsDisplay];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint touchPoint;
    UITouch *touch = [touches anyObject];
    if (touch) {
        touchPoint = [touch locationInView:self];
        for (int i=0; i<buttonArray.count; i++) {
            GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]);
//            判断是否经过密码区域
            if (CGRectContainsPoint(buttonTemp.frame,touchPoint)) {
//                判断是否保存过改密码区域编号(密码)
                if ([touchedArray containsObject:[NSString stringWithFormat:@"num%d",i]]) {
//                    设置为终点
                    lineEndPoint = touchPoint;
                    [self setNeedsDisplay];
                    return;
                }
//                添加密码
                [touchedArray addObject:[NSString stringWithFormat:@"num%d",i]];
                [buttonTemp setSelected:YES];
                [buttonTemp setNeedsDisplay];
//                添加密码点到触点列表
                CGRect frameTemp = buttonTemp.frame;
                CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/2,frameTemp.origin.y+frameTemp.size.height/2);
                NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",point.x],@"x",[NSString stringWithFormat:@"%f",point.y],@"y",[NSString stringWithFormat:@"%d",i],@"num", nil];
                [touchesArray addObject:dict];
                break;
            }
        }
//        把移动到的点做为线的终点,用于即时绘图(画线)
        lineEndPoint = touchPoint;
        [self setNeedsDisplay];
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    NSMutableString * resultString=[NSMutableString string];
    for ( NSDictionary * num in touchesArray ){
        if(![num objectForKey:@"num"])break;
//        生成密码
        [resultString appendString:[num objectForKey:@"num"]];
        NSLog(@"passward === %@   touchhes  == ",num);
    }
    if(style==1){
//        判断手势密码,进行对应操作
        success = [rerificationDelegate verification:resultString];
    }
    else {
        success = [resetDelegate resetPassword:resultString];
    }

    for (int i=0; i<touchesArray.count; i++) {
        NSInteger selection = [[[touchesArray objectAtIndex:i] objectForKey:@"num"]intValue];
        GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:selection]);
        [buttonTemp setSuccess:success];
        [buttonTemp setNeedsDisplay];
    }
    [self setNeedsDisplay];
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
//    if (touchesArray.count<2)return;
    for (int i=0; i<touchesArray.count; i++) {
        CGContextRef context = UIGraphicsGetCurrentContext();
        if (![[touchesArray objectAtIndex:i] objectForKey:@"num"]) { //防止过快滑动产生垃圾数据
            [touchesArray removeObjectAtIndex:i];
            continue;
        }
//        画线
        if (success) {
            CGContextSetRGBStrokeColor(context, 251/255.f, 187/255.f, 20/255.f, 1.0);//金色
        }
        else {
            CGContextSetRGBStrokeColor(context, 251/255.f, 187/255.f, 20/255.f, 1.0);//金色
        }
//        线宽
        CGContextSetLineWidth(context,5);
//        设置目标线段终点
        CGContextMoveToPoint(context, [[[touchesArray objectAtIndex:i] objectForKey:@"x"] floatValue], [[[touchesArray objectAtIndex:i] objectForKey:@"y"] floatValue]);
//        如果不是最后一个密码点
        if (i<touchesArray.count-1) {
//            再次连线到下一个密码点
            CGContextAddLineToPoint(context, [[[touchesArray objectAtIndex:i+1] objectForKey:@"x"] floatValue],[[[touchesArray objectAtIndex:i+1] objectForKey:@"y"] floatValue]);
        }
        else{
            if (success) {
//                如果是最后一个点,则连线到终点
                CGContextAddLineToPoint(context, lineEndPoint.x,lineEndPoint.y);
            }
        }
        CGContextStrokePath(context);
    }
}

注意事项:
1、如果最后的连线的位置不是密码点,则取消最后一个密码到手势终点的连线(这一步的完成并不是删除,只是在手势完成之后线段的重新绘制)
2、关于style的说明,手势密码使用过程中的对应状态(可分为验证手势密码和设置手势密码,所以相对应的调用方法)
3、关于success的说明,button的success是在非填充图片的情况下使用的
TentacleView的success是用来相button传递数据的
4、关于button(密码点)可以自定义样式和响应事件,在此不做描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值