手势解锁功能的实现(案例:支付宝手势解锁界面)

/*

说明:总共四个文件


包含:

ViewController.h

ViewController.h

FFFView.h

FFFView.h

*/


#import "ViewController.h"

#import "FFFView.h"

#import "TestViewController.h"


@interface ViewController ()

@property (weak, nonatomic) IBOutlet FFFView* passwordView;

@property (weak, nonatomic) IBOutlet UIImageView* imageView;

@end


@implementation ViewController


- (void)viewDidLoad

{

    [super viewDidLoad];

    // 设置背景图片

    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Home_refresh_bg"]];

    

    self.passwordView.pwdBlock = ^(NSString* pwd, UIImage* img) {

        // 密码

        NSString* pwd1 = @"012";

        if ([pwd isEqualToString:pwd1]) {

            NSLog(@"密码正确");

            // 跳转

            TestViewController* vc = [[TestViewController alloc] init];

            vc.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"main"]];

            [self presentViewController:vc animated:YES completion:nil];

            self.imageView.image = nil;

            return YES;

        }

        else {

            NSLog(@"密码错误");

            self.imageView.image = img;

            return NO;

        }

   };

}

@end


//============================================//

#import <UIKit/UIKit.h>


@interface FFFView : UIView


@property (nonatomic, copy) BOOL (^pwdBlock)(NSString*, UIImage*);


@end


//============================================//

#import "FFFView.h"

#import "SVProgressHUD.h"


#define kBtnCount 9


@interface CZView ()


@property (nonatomic, strong) NSMutableArray* btns;


@property (nonatomic, strong) NSMutableArray* lineBtns;


@property (nonatomic, assign) CGPoint currentPoint;


@end


@implementation FFFView


// 初始化 需要画线的数组

- (NSMutableArray*)lineBtns

{

    if (!_lineBtns) {

        _lineBtns = [NSMutableArray array];

    }

    return _lineBtns;

}


// 初始化 数组 所有的按钮

- (NSMutableArray*)btns

{

    if (!_btns) {

        _btns = [NSMutableArray array];


        // 创建 9 btn

        for (int i = 0; i < kBtnCount; i++) {

            UIButton* btn = [[UIButton alloc] init];

            // 绑定tag 相当于密码

            btn.tag = i;

            [btn setUserInteractionEnabled:NO];

            // 设置默认的按钮样式

            [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];

            // 设置高亮的图片

            [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateHighlighted];

            // 设置错误的样式

            [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_error"] forState:UIControlStateSelected];

            // 添加到数组当中

            [self.btns addObject:btn];

            [self addSubview:btn];

        }

    }

    return _btns;

}


// 触摸view的时候 调用

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event

{

    // 获取touch对象

    UITouch* t = touches.anyObject;

    // 获取点击的点

    CGPoint point = [t locationInView:t.view];


    // 遍历所有的按钮

    for (int i = 0; i < self.btns.count; i++) {

        UIButton* btn = self.btns[i];

        // 按钮的frame是否包含了点击的点

        if (CGRectContainsPoint(btn.frame, point)) {

            btn.highlighted = YES;

            // 判断这个按钮是不是已经添加到了 数组当中 如果没有再添加

            if (![self.lineBtns containsObject:btn]) {

                // 添加到需要连线的数组当中

                [self.lineBtns addObject:btn];

            }

        }

    }

}


// 手指移动

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event

{

    // 获取touch对象

    UITouch* t = touches.anyObject;

    // 获取点击的点

    CGPoint point = [t locationInView:t.view];


    // 获取移动时候手指的位置

    self.currentPoint = point;


    // 遍历所有的按钮

    for (int i = 0; i < self.btns.count; i++) {

        UIButton* btn = self.btns[i];

        // 按钮的frame是否包含了点击的点

        if (CGRectContainsPoint(btn.frame, point)) {

            btn.highlighted = YES;

            // 判断这个按钮是不是已经添加到了 数组当中 如果没有再添加

            if (![self.lineBtns containsObject:btn]) {

                // 添加到需要连线的数组当中

                [self.lineBtns addObject:btn];

            }

        }

    }


    // 重绘

    [self setNeedsDisplay];

}


// 手指抬起

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event

{


    // 解决 错误的时候 最后手指的位置不连接

    self.currentPoint = [[self.lineBtns lastObject] center];

    [self setNeedsDisplay];


    NSString* password = @"";


    // 输出密码

    for (int i = 0; i < self.lineBtns.count; i++) {

        // 拼接按钮的tag

        password = [password stringByAppendingString:[NSString stringWithFormat:@"%ld", [self.lineBtns[i] tag]]];

    }


    for (int i = 0; i < self.lineBtns.count; i++) {

        UIButton* btn = self.lineBtns[i];

        btn.selected = YES;

        btn.highlighted = NO;

    }


    // 开启上下文

    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);

    // 获取上下文

    CGContextRef ctx = UIGraphicsGetCurrentContext();


    [self.layer renderInContext:ctx];


    // 通过上下文获取图片

    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();


    // 关闭上下文

    UIGraphicsEndImageContext();


    

    if (self.pwdBlock) {

        if (self.pwdBlock(password, image)) {

            [SVProgressHUD showSuccessWithStatus:@"密码正确"];

            [self clear];

        }

        else {

            [SVProgressHUD showErrorWithStatus:@"密码错误"];

        }

    }


    // 在恢复之前 不能让用户进行连线

    [self setUserInteractionEnabled:NO];

    // 显示错误的样式 1秒钟

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        // 恢复以后再把用户交互打开

        [self setUserInteractionEnabled:YES];

        [self clear];

    });

}


// 恢复到初始的状态

- (void)clear

{

    // 遍历所有的按钮

    for (int i = 0; i < self.btns.count; i++) {

        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++) {

        if (i == 0) {

            [path moveToPoint:[self.lineBtns[i] center]];

        }

        else {

            [path addLineToPoint:[self.lineBtns[i] center]];

        }

    }


    if (self.lineBtns.count) {

        // 连接到手指的位置

        [path addLineToPoint:self.currentPoint];

    }


    // 设置颜色

    [[UIColor whiteColor] set];


    // 设置线宽

    [path setLineWidth:10];

    // 设置连接处的样式

    [path setLineJoinStyle:kCGLineJoinRound];

    // 设置头尾的样式

    [path setLineCapStyle:kCGLineCapRound];


    // 渲染

    [path stroke];

}


// 布局九宫格

- (void)layoutSubviews

{

    [super layoutSubviews];


    // 计算九宫格位置

    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




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值