1.LockController
#import "LockController.h"
#import "LockView.h"
#import "UIView+Extension.h"
#define KSCREENW [UIScreen mainScreen].bounds.size.width
#define KSCREENH [UIScreen mainScreen].bounds.size.height
@interface LockController ()<LockViewDelegate>
//@property (weak, nonatomic) IBOutlet UILabel *locklabel;
@property(nonatomic,weak)UILabel *unlocklabel;
@property(nonatomic,weak)UILabel *setpassword;
//标记是否是重置密码
@property(nonatomic ,assign,getter=isresetpassword)BOOL resetpassword;
//判断是否是两次确认密码
@property(nonatomic,assign,getter=istwopassword)BOOL twopassword;
@property(weak,nonatomic)LockView *lockview;
@end
@implementation LockController
- (void)viewDidLoad {
[super viewDidLoad];
self.resetpassword = NO;
self.twopassword = NO;
LockView *lockview = [[LockView alloc]init];
lockview.backgroundColor = [UIColor clearColor];
lockview.width = 300;
lockview.height = 300;
lockview.x = (KSCREENW - lockview.width) * 0.5;
lockview.y = 150;
self.lockview = lockview;
lockview.delegate = self;
[self.view addSubview:lockview];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"HomeButtomBG"]];
self.lockview.delegate = self;
[self judgeMentLocalPassWord];
}
//设置状态栏颜色
- (UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
//添加重置密码按钮
- (void)addResetPassWordBuutton{
UIButton *resetpassword = [[UIButton alloc]init];
[resetpassword setTitle:@"重置密码" forState:UIControlStateNormal];
[resetpassword setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[resetpassword sizeToFit];
resetpassword.y = CGRectGetMaxY(self.lockview.frame) + 50;
resetpassword.x = (KSCREENW - resetpassword.width) * 0.5;
[self.view addSubview:resetpassword];
[resetpassword addTarget:self action:@selector(resetPassWord) forControlEvents:UIControlEventTouchUpInside];
}
//添加下次设置按钮
- (void)addCancelButton{
UIButton *cancelbutt = [[UIButton alloc]init];
[cancelbutt setTitle:@"下次设置" forState:UIControlStateNormal];
[cancelbutt setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[cancelbutt sizeToFit];
cancelbutt.y = CGRectGetMaxY(self.lockview.frame) + 50;
cancelbutt.x = (KSCREENW - cancelbutt.width) * 0.5;
[self.view addSubview:cancelbutt];
[cancelbutt addTarget:self action:@selector(cancelButtonClick) forControlEvents:UIControlEventTouchUpInside];
}
//添加重置密码和取消设置的按钮
//- (void)addResetPassWordButtAndCancelButt{
//
// UIButton *resetpassword = [[UIButton alloc]init];
// [resetpassword setTitle:@"重置密码" forState:UIControlStateNormal];
// [resetpassword setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
// [resetpassword sizeToFit];
// resetpassword.y = 500;
// resetpassword.x = 80;
// [self.view addSubview:resetpassword];
// [resetpassword addTarget:self action:@selector(resetPassWord) forControlEvents:UIControlEventTouchUpInside];
//
//
// UIButton *cancelbutt = [[UIButton alloc]init];
// [cancelbutt setTitle:@"下次设置" forState:UIControlStateNormal];
// [cancelbutt setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
// [cancelbutt sizeToFit];
// cancelbutt.y = 500;
// cancelbutt.x = CGRectGetMaxX(resetpassword.frame) + 50;
// [self.view addSubview:cancelbutt];
// [cancelbutt addTarget:self action:@selector(cancelButtonClick) forControlEvents:UIControlEventTouchUpInside];
//
//}
//取消设置按钮
- (void)cancelButtonClick{
[self dismissViewControllerAnimated:YES completion:nil];
}
//重置按钮点击事件
- (void)resetPassWord{
self.resetpassword = YES;
[self setLocklabel:@"确认旧手势密码"];
[self.unlocklabel sizeToFit];
self.unlocklabel.x = (KSCREENW - self.unlocklabel.width) * 0.5;
self.unlocklabel.y = CGRectGetMinY(self.lockview.frame) - 40;
}
//lockview的代理方法
- (BOOL)unlockView:(LockView *)unlockView withPassword:(NSString *)password
{
NSString *localpasswordone = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordone"];
NSString *localpasswordtwo = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordtwo"];
if (self.twopassword) {
if ([localpasswordone isEqualToString:localpasswordtwo]) {
UIAlertView *confirmalertview = [[UIAlertView alloc]initWithTitle:@"密码设置成功" message:@"请输入密码解锁" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil, nil];
[confirmalertview show];
[self setLocklabel:@"手势解锁"];
self.twopassword = NO;
return YES;
}
else
{
UIAlertView *alertview = [[UIAlertView alloc]initWithTitle:@"与上次密码不对应" message:@"请重新设置密码" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil, nil];
[alertview show];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"passwordone"];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"passwordtwo"];
[self setLocklabel:@"设置密码"];
return NO;
}
}
else
{
if ([password isEqualToString:localpasswordone]) {
if (self.isresetpassword) {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"passwordone"];
[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"passwordtwo"];
[self setLocklabel:@"设置新密码"];
UIAlertView *resetalertview = [[UIAlertView alloc]initWithTitle:@"密码确认成功" message:@"请重新设置密码" delegate:self cancelButtonTitle:@"确认" otherButtonTitles:nil, nil];
[resetalertview show];
self.resetpassword = NO;
}
else
{
[self dismissViewControllerAnimated:YES completion:nil];
}
return YES;
}
else {
return NO;
}
return NO;
}
}
- (void)setPassWordSuccess:(NSString *)tabelname{
NSString *localpasswordone = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordone"];
NSString *localpasswordtwo = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordywo"];
if (!localpasswordtwo||!localpasswordone ) {
self.twopassword = YES;
}
self.setpassword.text = tabelname;
self.unlocklabel.text = tabelname;
[self.unlocklabel sizeToFit];
[self.setpassword sizeToFit];
self.setpassword.x = (KSCREENW - self.setpassword.width) * 0.5;
self.setpassword.y = CGRectGetMinY(self.lockview.frame) - 40;
self.unlocklabel.x = (KSCREENW - self.unlocklabel.width) * 0.5;
self.unlocklabel.y = CGRectGetMinY(self.lockview.frame) - 40;
}
//判断本地是否存有密码
- (void)judgeMentLocalPassWord{
NSString *password = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordone"];
if (password == nil) {
//添加下次设置按钮
[self addCancelButton];
[self setPassWordView:@"设置手势密码"];
}else{
//添加重置密码按钮
[self addResetPassWordBuutton];
[self unlockView:@"手势解锁"];
}
}
//设置密码界面
- (void)setPassWordView:(NSString *)lockstr{
UILabel *locklabel = [[UILabel alloc]init];
locklabel.text = lockstr;
locklabel.textAlignment = NSTextAlignmentCenter;
self.setpassword = locklabel;
locklabel.textColor = [UIColor whiteColor];
[locklabel sizeToFit];
locklabel.x = (KSCREENW - locklabel.width) * 0.5;
locklabel.y = CGRectGetMinY(self.lockview.frame) - 40;
[self.view addSubview:locklabel];
}
- (void)setLocklabel:(NSString *)locklstr{
self.setpassword.text = locklstr;
self.unlocklabel.text = locklstr;
[self.setpassword sizeToFit];
[self.unlocklabel sizeToFit];
self.setpassword.x = (KSCREENW - self.setpassword.width) * 0.5;
self.setpassword.y = CGRectGetMinY(self.setpassword.frame) - 40;
self.unlocklabel.x = (KSCREENW - self.unlocklabel.width) * 0.5;
self.unlocklabel.y = CGRectGetMinY(self.lockview.frame) - 40;
[self.view addSubview:self.setpassword];
[self.view addSubview:self.unlocklabel];
}
//手势解锁界面
- (void)unlockView:(NSString *)unlockstr{
UILabel *locklabel = [[UILabel alloc]init];
self.unlocklabel = locklabel;
locklabel.text = unlockstr;
locklabel.textColor = [UIColor whiteColor];
[locklabel sizeToFit];
locklabel.x = (KSCREENW - locklabel.width) * 0.5;
locklabel.y = CGRectGetMinY(self.lockview.frame) - 40;
[self.view addSubview:locklabel];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
2. LockView
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, passwordtype){
ResetPassWordType = 1,
UsePassWordType = 2,
};
@class LockView;
@protocol LockViewDelegate <NSObject>
- (BOOL)unlockView:(LockView *)unlockView withPassword:(NSString *)password;
- (void)setPassWordSuccess:(NSString *)tabelname;
@end
@interface LockView : UIView
@property (nonatomic, weak) id<LockViewDelegate> delegate;
@end
#import "LockView.h"
#define SteveZLineColor [UIColor colorWithRed:0.0 green:170/255.0 blue:255/255.0 alpha:1.0]
@interface LockView ()
// 保存所有的按钮
@property (nonatomic, strong) NSArray* buttons;
// 保存所有“碰过”的按钮
@property (nonatomic, strong) NSMutableArray* selectedButtons;
// 定义一个线的颜色
@property (nonatomic, strong) UIColor *lineColor;
// 记录最后用户触摸的点
@property (nonatomic, assign) CGPoint currentPoint;
@end
@implementation LockView
- (UIColor *)lineColor
{
if (_lineColor == nil) {
_lineColor = SteveZLineColor;
}
return _lineColor;
}
- (NSMutableArray*)selectedButtons
{
if (_selectedButtons == nil) {
_selectedButtons = [NSMutableArray array];
}
return _selectedButtons;
}
- (NSArray*)buttons
{
if (_buttons == nil) {
// 创建9个按钮
NSMutableArray* arrayM = [NSMutableArray array];
for (int i = 0; i < 9; i++) {
UIButton *button=[[UIButton alloc]init];
button.tag = i;
button.userInteractionEnabled = NO;
// 设置按钮的背景图片
[button setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
[button setBackgroundImage:[UIImage imageNamed:@"gesture_node_error"] forState:UIControlStateDisabled];
[self addSubview:button];
[arrayM addObject:button];
}
_buttons = arrayM;
}
return _buttons;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// 设置每个按钮的frame
CGFloat w = 74;
CGFloat h = 74;
// 列(和行)的个数
int columns = 3;
// 计算水平方向和垂直方向的间距
CGFloat marginX = (self.frame.size.width - columns * w) / (columns + 1);
CGFloat marginY = (self.frame.size.height - columns * h) / (columns + 1);
// 计算每个按钮的x 和 y
for (int i = 0; i < self.buttons.count; i++) {
UIButton* button = self.buttons[i];
// 计算当前按钮所在的行号
int row = i / columns;
// 计算当前按钮所在的列索引
int col = i % columns;
CGFloat x = marginX + col * (w + marginX);
CGFloat y = marginY + row * (h + marginY);
button.frame = CGRectMake(x, y, w, h);
}
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
// 1. 获取当前触摸的点
UITouch* touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
// 2. 循环判断当前触摸的点在哪个按钮的范围之内, 找到对一个的按钮之后, 把这个按钮的selected = YES
for (int i = 0; i < self.buttons.count; i++) {
UIButton* button = self.buttons[i];
if (CGRectContainsPoint(button.frame, loc) && !button.selected) {
button.selected = YES;
[self.selectedButtons addObject:button];
break;
}
}
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
// 1. 获取当前触摸的点
UITouch* touch = touches.anyObject;
CGPoint loc = [touch locationInView:touch.view];
self.currentPoint = loc;
// 2. 循环判断当前触摸的点在哪个按钮的范围之内, 找到对一个的按钮之后, 把这个按钮的selected = YES
for (int i = 0; i < self.buttons.count; i++) {
UIButton* button = self.buttons[i];
if (CGRectContainsPoint(button.frame, loc) && !button.selected) {
button.selected = YES;
[self.selectedButtons addObject:button];
break;
}
}
// 3. 重绘
[self setNeedsDisplay];
}
// 手指抬起事件
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// 1. 获取用户绘制的密码
NSMutableString *password = [NSMutableString string];
for (UIButton *button in self.selectedButtons) {
[password appendFormat:@"%@", @(button.tag)];
}
//获取本地的密码
NSString *localpassone = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordone"];
NSString *localpasstwo = [[NSUserDefaults standardUserDefaults]objectForKey:@"passwordtwo"];
if (!localpassone||!localpasstwo) {
if (!localpassone) {
//保存用户绘制的密码
[[NSUserDefaults standardUserDefaults]setObject:password forKey:@"passwordone"];
if ([self.delegate respondsToSelector:@selector(setPassWordSuccess:)]) {
[self.delegate setPassWordSuccess:@"再次输入新密码"];
}
[self clear];
}else{
//保存用户绘制的密码
[[NSUserDefaults standardUserDefaults]setObject:password forKey:@"passwordtwo"];
if ([self.delegate respondsToSelector:@selector(setPassWordSuccess:)]) {
[self.delegate setPassWordSuccess:@"手势解锁"];
}
[self clear];
[self confirmPassWord:password];
}
}else{
[self confirmPassWord:password];
}
// 3. 根据控制器返回的密码判断结果, 执行不同的重绘操作
//--------------------- 重绘 ---------------------------------
}
- (void)confirmPassWord:(NSString *)password{
// 2. 通过代理, 把密码传递给控制器, 在控制器中判断密码是否正确
if ([self.delegate respondsToSelector:@selector(unlockView:withPassword:)]) {
// 判断密码是否正确
if ([self.delegate unlockView:self withPassword:password]) {
// 密码正确
[self clear];
} else {
// 密码不正确
// 1. 重绘成红色效果
// 1.1 把selectedButtons中的每个按钮的selected = NO, enabled = NO
for (UIButton *button in self.selectedButtons) {
button.selected = NO;
button.enabled = NO;
}
// 1.2 设置线段颜色为红色
self.lineColor = [UIColor redColor];
// 1.3 重绘
[self setNeedsDisplay];
// 禁用与用户的交互
self.userInteractionEnabled = NO;
// 2. 等待0.5秒中, 然后再清空
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self clear];
self.userInteractionEnabled = YES;
});
}
} else {
[self clear];
}
}
//重新设置密码的判断逻辑
- (void)resetPassWord{
NSLog(@"kkkkk");
}
- (void)clear
{
// 先将所有selectedButtons中的按钮的selected 设置为NO
for (UIButton *button in self.selectedButtons) {
button.selected = NO;
button.enabled = YES;
}
self.lineColor = SteveZLineColor;
// 移除所有的按钮
[self.selectedButtons removeAllObjects];
// 重绘
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
// if (self.selectedButtons.count > 0) {
// // 需要绘图
// }
if (self.selectedButtons.count == 0) return;
UIBezierPath *path = [[UIBezierPath alloc] init];
// 循环获取每个按钮的中心点,然后连线
for (int i = 0; i < self.selectedButtons.count; i++) {
UIButton *button = self.selectedButtons[i];
if (i == 0) {
// 如果是第一个按钮, 那么就把这个按钮的中心点作为起点
[path moveToPoint:button.center];
} else {
[path addLineToPoint:button.center];
}
}
// 把最后手指的位置和最后一个按钮的中心点连起来
[path addLineToPoint:self.currentPoint];
// 设置线条颜色
[self.lineColor set];
// 渲染
[path stroke];
}
@end
3.UIView+Extension
#import <UIKit/UIKit.h>
@interface UIView (Extension)
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat height;
@property (nonatomic, assign) CGSize size;
@property (nonatomic, assign) CGFloat centerX;
@property (nonatomic, assign) CGFloat centerY;
@end
#import "UIView+Extension.h"
@implementation UIView (Extension)
- (void)setX:(CGFloat)x{
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (CGFloat)x{
return self.frame.origin.x;
}
- (void)setY:(CGFloat)y{
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
- (CGFloat)y{
return self.frame.origin.y;
}
- (void)setWidth:(CGFloat)width{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)width{
return self.frame.size.width;
}
- (void)setHeight:(CGFloat)height{
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
- (CGFloat)height{
return self.frame.size.height;
}
- (void)setCenterX:(CGFloat)centerX{
CGPoint point = self.center;
point.x = centerX;
self.center = point;
}
- (CGFloat)centerX{
return self.center.x;
}
- (void)setCenterY:(CGFloat)centerY{
CGPoint point = self.center;
point.y = centerY;
self.center = point;
}
- (CGFloat)centerY{
return self.center.y;
}
- (void)setSize:(CGSize)size{
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
- (CGSize)size{
return self.frame.size;
}
@end