手势解锁可以说是手机的一个标志了,几乎所有涉及到安全的软件都有手势解锁功能。其实实现起来也相当简单,虽然思路比较简单,但是对我来说注意点还是比较多的。
根控制器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
效果图展示: