图案解锁实例
LockView.m(继承UIView)
#import "LockView.h"
#define btn_width 80
@interface LockView()
//记录所有按钮的数组
@property (strong, nonatomic) NSMutableArray<UIButton*> *btnArray;
//记录连线经过的按钮的索引的数组
@property (strong, nonatomic) NSMutableArray<NSNumber*> *indexArr;
@property (assign, nonatomic) CGPoint currentPoint;
@end
@implementation LockView
//初始化界面,创建每个按钮,添加一个拖动手势
- (instancetype)init
{
if(self = [super init])
{
self.backgroundColor = [UIColor clearColor];
for(int i = 0; i < 9; i++)
{
UIButton *btn = [[UIButton alloc]init];
[btn setUserInteractionEnabled:NO];
[btn setTag:i];
[btn setImage:[UIImage imageNamed:@"unselected"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"selected"] forState:UIControlStateSelected];
[self addSubview:btn];
}
[self addPanEvent];
}
return self;
}
//对按钮进行布局
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat margin = (self.frame.size.width - btn_width * 3) / 4;
for(int i = 0; i < self.subviews.count; i++)
{
UIButton *btn = self.subviews[i];
int col = i % 3;
int row = i / 3;
CGFloat btnX = margin + col * (btn_width + margin);
CGFloat btnY = margin + row * (btn_width + margin);
btn.frame = CGRectMake(btnX, btnY, btn_width, btn_width);
}
}
- (NSMutableArray<UIButton*> *)btnArray
{
if(_btnArray == nil)
{
_btnArray = [NSMutableArray array];
}
return _btnArray;
}
//添加拖动事件
- (void)addPanEvent
{
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
[self addGestureRecognizer:pan];
}
//返回某个点所在的按钮
- (UIButton*)getButtonByPoint:(CGPoint) point
{
for(UIButton *btn in self.subviews)
{
if(CGRectContainsPoint(btn.frame, point))
{
return btn;
}
}
return nil;
}
//拖动事件处理
- (void)panGesture:(UIPanGestureRecognizer *)pan
{
if(pan.state == UIGestureRecognizerStateBegan)
{
//手势为开始按下时,找到手指对应的点所在的按钮
//如果点在某个按钮上,按钮数据加入该按钮
UIButton *btn = [self getButtonByPoint:[pan locationInView:self]];
if(btn != nil && !btn.selected)
{
btn.selected = YES;
[self.btnArray addObject:btn];
}
}
else if(pan.state == UIGestureRecognizerStateChanged)
{
//在手指移动过程中,检测手指经过的点是否在某按钮上,如果经过某按钮,按钮数组加入该按钮
self.currentPoint = [pan locationInView:self];
UIButton *btn = [self getButtonByPoint:self.currentPoint];
if(btn != nil && !btn.selected)
{
btn.selected = YES;
[self.btnArray addObject:btn];
}
}
else if(pan.state == UIGestureRecognizerStateEnded)
{
//手指离开屏幕,检测手势密码是否正确
//以下功能为,经过的按钮至少在3个以上,如果密码没有设定,则将这次的按钮索引序列记为初始密码,
//如果密码已经设定过,则比对密码是否与初始密码一致
if(self.btnArray.count >= 3)
{
if(self.indexArr == nil)
{
self.indexArr = [NSMutableArray array];
for(int i = 0; i < self.btnArray.count; i++)
{
[self.indexArr addObject:[NSNumber numberWithInt:(int)self.btnArray[i].tag]];
}
NSLog(@"手势密码设定成功");
[self postMessage:@"手势密码设定成功"];
}
else
{
BOOL isRight = NO;
if(self.indexArr.count == self.btnArray.count)
{
for(int i = 0; i < self.indexArr.count; i++)
{
NSLog(@"%zd----%zd",self.indexArr[i].integerValue,self.btnArray[i].tag);
isRight = self.indexArr[i].integerValue == self.btnArray[i].tag;
if(!isRight)break;
}
}
NSLog(@"%d",isRight);
if(isRight)
{
NSLog(@"输入手势与设定密码一致,解锁");
[self postMessage:@"输入手势与设定密码一致,解锁"];
}
else
{
NSLog(@"输入手势错误!");
[self postMessage:@"输入手势错误!"];
}
}
}
else
{
NSLog(@"至少要连3个圆圈");
[self postMessage:@"至少要连3个圆圈"];
}
[self.btnArray removeAllObjects];
for(UIButton *btn in self.subviews)
{
btn.selected = NO;
}
}
//重绘
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPath];
if(self.btnArray.count)
{
//按顺序绘制所有的点之间的连线
for(int i = 0; i < self.btnArray.count; i++)
{
UIButton *btn = self.btnArray[i];
if(i == 0)
{
[path moveToPoint:btn.center];
}
else
{
[path addLineToPoint:btn.center];
}
}
[path addLineToPoint:self.currentPoint];
[[UIColor colorWithRed:0.0f/255 green:255.0f/255 blue:0.0f/255 alpha:0.5] setStroke];
[path setLineWidth:10];
[path setLineJoinStyle:kCGLineJoinRound];
[path stroke];
}
}
- (void)postMessage:(NSString*)msg
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"pathEnd" object:@{@"msg" : msg}];
}
@end
ViewController.m
#import "ViewController.h"
#import "LockView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImageView *backgroundView = [[UIImageView alloc]init];
backgroundView.frame = [UIScreen mainScreen].bounds;
backgroundView.image = [UIImage imageNamed:@"IMG_2511"];
[self.view addSubview:backgroundView];
LockView *lockView = [[LockView alloc]init];
CGFloat frameSize = [UIScreen mainScreen].bounds.size.width - 60;
lockView.frame = CGRectMake((self.view.frame.size.width - frameSize) * 0.5, (self.view.frame.size.height - frameSize) * 0.5, frameSize, frameSize);
[self.view addSubview:lockView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getMessage:) name:@"pathEnd" object:nil];
}
- (void)getMessage:(NSNotification*)notification
{
[self showAlertWithMessage:notification.object[@"msg"]];
}
- (void)showAlertWithMessage:(NSString*)msg
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:msg message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[alertController addAction:okAction];
[super presentViewController:alertController animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end