【UI基础】手势解锁简单实现

手势解锁可以说是手机的一个标志了,几乎所有涉及到安全的软件都有手势解锁功能。其实实现起来也相当简单,虽然思路比较简单,但是对我来说注意点还是比较多的。


根控制器view被我自定义一个新的view代替了:

//
//  BGView.m
//  05-手势解锁
//
//  Created by styshy on 15/11/4.
//  Copyright (c) 2015年 sz. All rights reserved.
//

#import "BGView.h"

@implementation BGView

// 在drawRect中绘制图片
- (void)drawRect:(CGRect)rect{
    UIImage *image = [UIImage imageNamed:@"Home_refresh_bg"];
    [image drawInRect:rect];
}

@end


主要的手势解锁在LockView这个类当中,部分代码有注释

//
//  LockView.m
//  05-手势解锁
//
//  Created by styshy on 15/11/4.
//  Copyright (c) 2015年 sz. All rights reserved.
//

#import "LockView.h"

@interface LockView ()

@property (nonatomic,strong) NSMutableArray *buttons;
@property (nonatomic,assign) CGPoint curP;

@end

@implementation LockView

// 懒加载
- (NSMutableArray *)buttons{
    if (_buttons == nil) {
        _buttons = [NSMutableArray array];
    }
    return _buttons;
}

// 添加按钮
- (void)awakeFromNib{
    
    for (int i = 0; i < 9; i ++) {
        // 创建按钮
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        
        // 设置按钮的背景图片
        [button setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
        [button setBackgroundImage:[UIImage imageNamed:@"gesture_node_selected"] forState:UIControlStateSelected];
        
        [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
        
        // 将按钮添加到视图当中
        [self addSubview:button];
    }
}

// 按钮的高亮状态是系统自动达到的,当用户长按按钮的时候就会达到高亮状态
// 按钮的选中状态必须通过代码手动达到
- (void)btnClick:(UIButton *)btn{
    btn.selected = YES;
}

// 布局按钮
- (void)layoutSubviews{
    
    [super layoutSubviews];
    
    CGFloat WH = 74;
    CGFloat btnX = 0;
    CGFloat btnY = 0;
    int totalCols = 3;
    int btnCol = 0;
    int btnRow = 0;
    
    CGFloat margin = (self.bounds.size.width - totalCols * WH)/(totalCols + 1);
    
    int count = (int)self.subviews.count;
    
    for (int i = 0; i < count; i ++) {
        // 当前按钮的所在列
        btnCol =(int) i % totalCols;
        // 当前按钮所在行
        btnRow = i / totalCols;
        // 当前按钮的x坐标
        btnX = margin + btnCol * (margin + WH);
        // 当前按钮的y坐标
        btnY = margin + btnRow * (margin + WH);
        
        UIButton *button = self.subviews[i];
        
        button.frame = CGRectMake(btnX, btnY, WH,WH);
        // 将按钮的交互状态转给drawRect方法处理
        button.userInteractionEnabled = NO;
        
        // 记录按钮,每个按钮都有一个数字标示
        button.tag = i;
        
    }
}

// 手势移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    // 获取手势
    UITouch *touch = [touches anyObject];
    // 获取当前的位置坐标
    CGPoint point = [touch locationInView:self];
    self.curP = point;

    for (UIButton* button in self.subviews) {
        // 判断当前按钮是否被选中
        if (CGRectContainsPoint(button.frame, point)) {
            if (button.selected == NO) {
                button.selected = YES;
                [self.buttons addObject:button];
            }
        }
    }
    
    // 重回
    [self setNeedsDisplay];
}

// 手势结束
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    
    NSMutableString *str = [NSMutableString string];
    for (UIButton * btn in self.buttons) {
        [str appendFormat:@"%ld",btn.tag];
        btn.selected = NO;
    }
    NSLog(@"%@",str);
    
    // 清空所有的选中按钮
    [self.buttons removeAllObjects];
    
    // 重新绘图
    [self setNeedsDisplay];
}

// 绘图
- (void)drawRect:(CGRect)rect{
    // 如果没有选中的按钮,则直接返回
    if (self.buttons.count == 0) return;
    
    
    // 创建路径
    UIBezierPath *path = [[UIBezierPath alloc] init];

    
    int count = (int)self.buttons.count;
    
    // 去除path,绘制线条
    for (int i = 0; i< count; i ++) {
        UIButton *selectedBtn = self.buttons[i];
        if (0 == i) {
            [path moveToPoint:selectedBtn.center];
        }else{
            [path addLineToPoint:selectedBtn.center];
        }
    }
    
    [path addLineToPoint:self.curP];
    
    [path setLineWidth:8];// 设置线宽
    [[UIColor greenColor] set];//设置线条颜色
    [path stroke];//绘制空心线条
    
}

@end


效果图展示:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值