公司项目中除了之前的指纹解锁外,还有手势解锁,这就扯到了手势解锁的功能实现
其实核心就是利用touchBegin,touchMoved和touchEnded三个事件,记录点击的按钮,并且绘制出线条即可
代码如下
ViewController.m
//
// ViewController.m
// TestPractise
//
// Created by 李昭宏 on 2017/1/13.
// Copyright © 2017年 scut. All rights reserved.
//
#import "ViewController.h"
#import "GestureView.h"
@interface ViewController ()
@property (strong, nonatomic) GestureView * gestureView;
@end
@implementation ViewController
#pragma mark - life cycle
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self configView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - private method
- (void)configView {
self.gestureView = [[GestureView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds),CGRectGetHeight([UIScreen mainScreen].bounds))];
[self.view addSubview:self.gestureView];
}
@end
核心 手势密码控件
GestureView.m
//
// GestureView.m
// TestPractise
//
// Created by 李昭宏 on 2017/1/16.
// Copyright © 2017年 scut. All rights reserved.
//
#import "GestureView.h"
@interface GestureView()
@property (nonatomic , strong) NSMutableArray *buttonArray;
@property (nonatomic , assign) CGPoint movePoint;
@end
@implementation GestureView {
UIColor *selectColor;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self configView];
selectColor = [self colorWithHexString:@"0x33a3ff"];
}
return self;
}
- (UIColor *)colorWithHexString:(NSString *)color{
NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
// String should be 6 or 8 characters
if ([cString length] < 6) {
return [UIColor clearColor];
}
// strip "0X" or "#" if it appears
if ([cString hasPrefix:@"0X"])
cString = [cString substringFromIndex:2];
if ([cString hasPrefix:@"#"])
cString = [cString substringFromIndex:1];
if ([cString length] != 6)
return [UIColor clearColor];
// Separate into r, g, b substrings
NSRange range;
range.location = 0;
range.length = 2;
//r
NSString *rString = [cString substringWithRange:range];
//g
range.location = 2;
NSString *gString = [cString substringWithRange:range];
//b
range.location = 4;
NSString *bString = [cString substringWithRange:range];
// Scan values
unsigned int r, g, b;
[[NSScanner scannerWithString:rString] scanHexInt:&r];
[[NSScanner scannerWithString:gString] scanHexInt:&g];
[[NSScanner scannerWithString:bString] scanHexInt:&b];
return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
}
- (void)configView {
self.backgroundColor = [self colorWithHexString:@"f5f5f5"];
for (int i = 0; i < 9; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
// 设置普通状态下的图片
[button setImage:[UIImage imageNamed:@"gestureButtonNormal"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"gestureButtonSelect"] forState:UIControlStateSelected];
// 不允许用户交互
button.userInteractionEnabled = NO;
[self addSubview:button];
CGFloat btnW = 64;
CGFloat btnH = 64;
CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat tolCol = 3;
CGFloat margin = ([UIScreen mainScreen].bounds.size.width - tolCol * btnW) / (tolCol + 1);
// 给按钮设置位置
button.tag = i;
NSInteger col = i % 3;
NSInteger row = i / 3;
btnX = margin + (margin + btnW) * col;
btnY = margin + (margin + btnH) * row;
button.frame = CGRectMake(btnX, btnY, btnW, btnH);
}
}
// 获取触摸点
- (CGPoint)pointWithTouches:(NSSet *)touches {
// 当前触摸点
UITouch *touch = [touches anyObject];
return [touch locationInView:self];
}
// 获取触摸按钮
- (UIButton *)buttonWithPoint:(CGPoint)point {
for (UIButton *button in self.subviews) {
if (CGRectContainsPoint(button.frame, point)) { // 点在按钮上
return button;
}
}
return nil;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// 当前触摸点
CGPoint point = [self pointWithTouches:touches];
// 获取触摸按钮
UIButton *button = [self buttonWithPoint:point];
if (button && button.selected == NO) { // 有触摸按钮的时候才需要选中
button.selected = YES;
[self.buttonArray addObject:button];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// 当前触摸点
CGPoint point = [self pointWithTouches:touches];
self.movePoint = point;
// 获取触摸按钮
UIButton *button = [self buttonWithPoint:point];
if (button && button.selected == NO) { // 有触摸按钮的时候才需要选中
button.selected = YES;
[self.buttonArray addObject:button];
}
// 重绘
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (!self.buttonArray.count) {
return;
}
if (self.buttonArray.count<4) {
NSLog(@"至少需要连接4个点");
} else {
NSMutableString *str = [NSMutableString string];
for (UIButton *btn in self.buttonArray) {
[str appendFormat:@"%ld",(long)btn.tag];
}
NSLog(@"手势轨迹%@",str);
}
for (UIButton *button in self.buttonArray) {
button.selected = NO;
}
[self.buttonArray removeAllObjects];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
// Drawing code
if (!self.buttonArray.count)return;
UIBezierPath *path = [UIBezierPath bezierPath];
for (int i = 0; i < self.buttonArray.count; i++) {
UIButton *button = self.buttonArray[i];
if (i == 0) {
[path moveToPoint:button.center];
} else {
[path addLineToPoint:button.center];
}
}
// 所有选中按钮之间都连线
[path addLineToPoint:self.movePoint];
//
[selectColor setStroke];
path.lineWidth = 3;
path.lineJoinStyle = kCGLineJoinRound;
// 渲染到视图
[path stroke];
}
#pragma mark - getter
- (NSMutableArray *)buttonArray {
if (_buttonArray) {
return _buttonArray;
}
_buttonArray = [NSMutableArray array];
return _buttonArray;
}
@end