看着支付宝、QQ什么的都有那个手势解锁,光知道是用手势加贝塞尔曲线,但一直也没做个实例,正好辞职有时间,就写个Demo玩玩
首先storyBoard拖一个imageView,然后设置其背景图片,设置user Interaction Enable为YES,再拖一个View放在其imageView上,自定义view类,因为要排放9个按钮,所以直接在自定义类中创建其按钮即可。具体的直接上代码。
.h
//
// LockVIew.h
// LockScreenDemo
//
// Created by 程磊 on 15/5/8.
// Copyright (c) 2015年 程磊. All rights reserved.
//
#import <UIKit/UIKit.h>
@class LockVIew;
@protocol LockViewDelegate <NSObject>
@optional
- (void)lockView:(LockVIew *)lockView didFinishPath:(NSString *)path;
@end
@interface LockVIew : UIView
@property (nonatomic, assign) IBOutlet id<LockViewDelegate> delegate;
@end
.m
//
// LockVIew.m
// LockScreenDemo
//
// Created by 程磊 on 15/5/8.
// Copyright (c) 2015年 程磊. All rights reserved.
//
#import "LockVIew.h"
#define APP_WIDTH [UIScreen mainScreen].bounds.size.width
@interface LockVIew ()
@property (nonatomic, strong) NSMutableArray *buttonArray;//存放连接的按钮
@property (nonatomic, assign) CGPoint currentPoint;//如果当前连的按钮被选中或者是你拖动的点不在按钮上,存放你的手指拖动的点
@end
@implementation LockVIew
- (NSMutableArray *)buttonArray {
if (_buttonArray == nil) {
_buttonArray = [NSMutableArray array];
}
return _buttonArray;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
if (self.buttonArray.count == 0) {
return;
}
UIBezierPath *path = [UIBezierPath bezierPath];//创建一条贝塞尔曲线
path.lineWidth = 10;//设置其曲线宽度
path.lineJoinStyle = kCGLineCapRound;//设置其曲线连接样式
[[UIColor colorWithRed:1 green:0 blue:0 alpha:0.5] set];
for (int i = 0; i < self.buttonArray.count; i++) {
UIButton *btn = self.buttonArray[i];
if (i == 0) {//如果是第一个按钮,则将其曲线的起点放在其按钮上,否则则进行连线
[path moveToPoint:btn.center];
} else {
[path addLineToPoint:btn.center];
}
}
[path addLineToPoint:self.currentPoint];//如果不满足上述条件,按钮不存在则连接到临时点
[path stroke];
}
/**
* 此方法在视图由XIB或者StoryBoard创建时调用
*
*/
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self addButtons];
}
return self;
}
/**
* 此方法是由代码创建时调用
*/
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self addButtons];
}
return self;
}
/**
* 添加按钮
*/
- (void)addButtons {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(APP_WIDTH/3*i, 20+APP_WIDTH/3*j, APP_WIDTH/3, APP_WIDTH/3);
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateHighlighted];
btn.userInteractionEnabled = NO;
[self addSubview:btn];
btn.tag = i + j * 3 + 1;
}
}
}
/**
* 获取当前触摸点
*
*/
- (CGPoint)pointWithTouch:(NSSet *)touches {
UITouch *touch = touches.anyObject;
return [touch locationInView:self];
}
/**
* 根据触摸点获取按钮
*
*/
- (UIButton *)buttonWithPoint:(CGPoint)point {
for (UIButton *btn in self.subviews) {
if (CGRectContainsPoint(btn.frame, point)) {//判断某点在不在其frame上
return btn;
}
}
return nil;
}
/**
* 触摸一开始调用
*
*/
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//获取触摸起始点位置
CGPoint startPoint = [self pointWithTouch:touches];
//获取其button
UIButton *btn = [self buttonWithPoint:startPoint];
if (btn && btn.selected == NO) {
btn.selected = YES;
[self.buttonArray addObject:btn];
}
}
/**
* 触摸取消调用
*
*/
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesEnded:touches withEvent:event];
}
/**
* 触摸结束调用
*
*/
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if ([self.delegate respondsToSelector:@selector(lockView:didFinishPath:)]) {//代理,将连接的点参数传递到其controller上,判断你解锁的顺序对不对,这里用tag
NSMutableString *path = [NSMutableString string];
for (UIButton *btn in self.buttonArray) {
[path appendFormat:@"%d",btn.tag];
}
[self.delegate lockView:self didFinishPath:path];
}
[self.buttonArray makeObjectsPerformSelector:@selector(setSelected:) withObject:NO];//此方法很好用,两个参数分别是你要调用什么方法,传递什么参数,像这个,直接调用button的setSelected函数,将其设置为NO
[self.buttonArray removeAllObjects];
[self setNeedsDisplay];//刷新视图
}
/**
* 手指移动的时候调用
*、
*/
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
//获取触摸起始点位置
CGPoint startPoint = [self pointWithTouch:touches];
//获取其button
UIButton *btn = [self buttonWithPoint:startPoint];
if (btn && btn.selected == NO) {
btn.selected = YES;
[self.buttonArray addObject:btn];
} else {
self.currentPoint = startPoint;
}
[self setNeedsDisplay];
}
@end
ViewController.m文件
//
// ViewController.m
// LockScreenDemo
//
// Created by 程磊 on 15/5/8.
// Copyright (c) 2015年 程磊. All rights reserved.
//
#import "ViewController.h"
#import "LockVIew.h"
@interface ViewController () <LockViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)lockView:(LockVIew *)lockView didFinishPath:(NSString *)path {
if ([path isEqualToString:@"1236"]) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Warning" message:@"Success" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Sure" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancle" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
} else {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Waring" message:@"Failure" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Sure" style:UIAlertActionStyleDefault handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancle" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end