前序
最近公司APP要做改版,其中要使用手勢密碼鎖型宙,所以提前寫了一個小Demo練練手嘱能,該Demo參考了DBGuestureLock吝梅。這里將詳細闡述代碼細節(jié),希望可以幫助到需要幫助的人惹骂。
相關(guān)界面GIF
代碼實現(xiàn)
一苏携、創(chuàng)建相關(guān)類
- GesturePasswordButton
該類主要是表示手勢密碼中的圓點 - GesturePasswordView
該類是手勢密碼View - GesturePasswordViewController
該類是用于使用GesturePasswordView
二、繪制界面
從GIF圖可以看出对粪,手勢密碼一共有三種狀態(tài)(正常右冻、選擇、不正確)著拭,因此現(xiàn)在GesturePasswordView.h文件中創(chuàng)建一個枚舉類型
typedef NS_ENUM(NSInteger, GesturePasswordButtonState) {
GesturePasswordButtonStateNormal = 0,
GesturePasswordButtonStateSelected,
GesturePasswordButtonStateIncorrect,
};
根據(jù)Button的形狀纱扭,可以在GesturePasswordView.h中定義以下屬性(之所以寫在GesturePasswordView.h中是為了根據(jù)不同的狀態(tài)改變button的樣式)
@property (nonatomic, assign)CGFloat strokeWidth; //圓弧的寬度
@property (nonatomic, assign)CGFloat circleRadius; //半徑
@property (nonatomic, assign)CGFloat centerPointRadius; //中心圓半徑
@property (nonatomic, assign)CGFloat lineWidth; //連接線寬度
@property (nonatomic, strong)UIColor *strokeColor; //圓弧的填充顏色
@property (nonatomic, strong)UIColor *fillColor; //除中心圓點外 其他部分的填充色
@property (nonatomic, strong)UIColor *centerPointColor; //中心圓點的顏色
@property (nonatomic, strong)UIColor *lineColor; //線條填充顏色
@property (nonatomic, assign)BOOL showCenterPoint; //是否顯示中心圓
@property (nonatomic, assign)BOOL fillCenterPoint; //是否填充中心圓
在GesturePasswordView.m文件中定義以下屬性,用于后面的代碼編寫茫死。(GesturePasswordStatus枚舉類型將會在后面寫出)
@property (nonatomic, strong) NSMutableArray *selectorAry;//存儲已經(jīng)選擇的按鈕
@property (nonatomic, assign)CGPoint currentPoint;//當(dāng)前處于哪個按鈕范圍內(nèi)
@property (nonatomic, assign)GesturePasswordStatus status;//當(dāng)前控件器所處狀態(tài)(設(shè)置跪但、重新設(shè)置、登錄)
@property (nonatomic, assign)NSInteger inputNum;//輸入的次數(shù)
@property (nonatomic, assign)NSInteger resetInputNum;//重置密碼時驗證舊密碼 輸入的次數(shù)
@property (nonatomic, strong)NSString *firstPassword;//表示設(shè)置密碼時 第一次輸入的手勢密碼
在GesturePasswordView.m文件中寫一個方法來改變button當(dāng)前的屬性值
- (void)setPropertiesByState:(GesturePasswordButtonState)buttonState{
switch (buttonState) {
case GesturePasswordButtonStateNormal:
self.fillCenterPoint = YES;
self.showCenterPoint = YES;
self.strokeWidth = 1.f;
self.centerPointRadius = 10.f;
self.lineWidth = 2.f;
self.lineColor = [UIColor whiteColor];
self.fillColor = [UIColor whiteColor];
self.strokeColor = [UIColor whiteColor];
self.centerPointColor = [UIColor grayColor];
break;
case GesturePasswordButtonStateSelected:
self.fillCenterPoint = YES;
self.showCenterPoint = YES;
self.strokeWidth = 1.f;
self.centerPointRadius = 10.f;
self.lineWidth = 2.f;
self.lineColor = [UIColor greenColor];
self.fillColor = RGBA(127, 255, 212, 1);
self.strokeColor = RGBA(127, 255, 212, 1);
self.centerPointColor = [UIColor greenColor];
break;
case GesturePasswordButtonStateIncorrect:
self.fillCenterPoint = YES;
self.showCenterPoint = YES;
self.strokeWidth = 1.f;
self.centerPointRadius = 10.f;
self.lineWidth = 2.f;
self.lineColor = [UIColor orangeColor];
self.fillColor = RGBA(255, 245, 238, 1);
self.strokeColor = RGBA(255, 245, 238, 1);
self.centerPointColor = [UIColor orangeColor];
break;
default:
break;
}
}
在GesturePasswordView.m文件中使用initWithFrame:(CGRect)frame方法繪制手勢圖,這里GesturePasswordView的大小以(320峦萎,320)為基準(zhǔn)屡久。
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.selectorAry = [[NSMutableArray alloc] init];
[self setPropertiesByState:GesturePasswordButtonStateNormal];
NSInteger distance = 320/3;
NSInteger size = distance/1.5;
NSInteger margin = size/4;
float ins = (SCREEN_WIDTH-320)/2;
self.circleRadius = size/2;
for (int i = 0; i < 9; i++) {
NSInteger row = i/3;
NSInteger col = i%3;
GesturePasswordButton *gesturePasswordButton = [[GesturePasswordButton alloc] initWithFrame:CGRectMake(ins+col*distance+margin, row*distance+margin, size, size)];
[gesturePasswordButton setTag:i+1];
[self addSubview:gesturePasswordButton];
}
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
在GesturePasswordButton.m文件中重新initWithFrame:(CGRect)frame方法。
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled = NO;
}
return self;
}
在GesturePasswordButton.m文件中重新- (void)drawRect:(CGRect)rect方法爱榔。
- 獲取到父視圖(GesturePasswordView)被环,使用其相關(guān)描述button的屬性。
__weak GesturePasswordView *gesView = nil;
if ([self.superview isKindOfClass:[GesturePasswordView class]]) {
gesView = (GesturePasswordView *)self.superview;
}
- 繪制外圈大圓
CGFloat radius = gesView.circleRadius - gesView.strokeWidth;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, gesView.strokeWidth);
CGPoint centerPoint = CGPointMake(rect.size.width/2, rect.size.height/2);
CGFloat startAngle = -((CGFloat)M_PI/2);
CGFloat endAngle = ((2 * (CGFloat)M_PI) + startAngle);
[gesView.strokeColor setStroke];
CGContextAddArc(context, centerPoint.x, centerPoint.y, radius+gesView.strokeWidth/2, startAngle, endAngle, 0);
CGContextStrokePath(context);//CGContextStrokePath來描線,即形狀
- 根據(jù)是否顯示中心點繪制形狀
if (gesView.showCenterPoint) {
[gesView.fillColor set];//同時設(shè)置填充和邊框色
CGContextAddArc(context, centerPoint.x, centerPoint.y, radius, startAngle, endAngle, 0);
CGContextFillPath(context);//CGContextFillPath來填充形狀內(nèi)的顏色
if (gesView.fillCenterPoint) {
[gesView.centerPointColor set];//同時設(shè)置填充和邊框色
}else{
[gesView.centerPointColor setStroke];//設(shè)置邊框色
}
CGContextAddArc(context, centerPoint.x, centerPoint.y, gesView.centerPointRadius, startAngle, endAngle, 0);
if (gesView.fillCenterPoint) {
CGContextFillPath(context);//CGContextFillPath來填充形狀內(nèi)的顏色
}else{
CGContextStrokePath(context);//CGContextStrokePath來描線,即形狀
}
}
整體drawRect方法如下:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
__weak GesturePasswordView *gesView = nil;
if ([self.superview isKindOfClass:[GesturePasswordView class]]) {
gesView = (GesturePasswordView *)self.superview;
}
CGFloat width = rect.size.height > rect.size.width ? rect.size.width : rect.size.height;
CGFloat radius = (width - 2*gesView.strokeWidth)/2;
if (radius > (gesView.circleRadius - gesView.strokeWidth)) {
radius = gesView.circleRadius - gesView.strokeWidth;
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, gesView.strokeWidth);
CGPoint centerPoint = CGPointMake(rect.size.width/2, rect.size.height/2);
CGFloat startAngle = -((CGFloat)M_PI/2);
CGFloat endAngle = ((2 * (CGFloat)M_PI) + startAngle);
[gesView.strokeColor setStroke];
CGContextAddArc(context, centerPoint.x, centerPoint.y, radius+gesView.strokeWidth/2, startAngle, endAngle, 0);
CGContextStrokePath(context);//CGContextStrokePath來描線,即形狀
if (gesView.showCenterPoint) {
[gesView.fillColor set];//同時設(shè)置填充和邊框色
CGContextAddArc(context, centerPoint.x, centerPoint.y, radius, startAngle, endAngle, 0);
CGContextFillPath(context);//CGContextFillPath來填充形狀內(nèi)的顏色
if (gesView.fillCenterPoint) {
[gesView.centerPointColor set];//同時設(shè)置填充和邊框色
}else{
[gesView.centerPointColor setStroke];//設(shè)置邊框色
}
CGContextAddArc(context, centerPoint.x, centerPoint.y, gesView.centerPointRadius, startAngle, endAngle, 0);
if (gesView.fillCenterPoint) {
CGContextFillPath(context);//CGContextFillPath來填充形狀內(nèi)的顏色
}else{
CGContextStrokePath(context);//CGContextStrokePath來描線,即形狀
}
}
}
這樣的話只需要在GesturePasswordViewController中加載GesturePasswordView就可以顯示出手勢密碼的界面详幽。
三筛欢、實現(xiàn)三種手勢狀態(tài)
為了實現(xiàn)手勢的三種狀態(tài),我們需要獲取到用戶的觸摸動作唇聘,這里我們將使用UIResponder類版姑,UIResponder類是專門用來響應(yīng)用戶的操作處理各種事件的,所以我們需要在GesturePasswordView.m實現(xiàn)touchesBegan迟郎、touchesMoved剥险、touchesEnded方法。
- touchesBegan方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];//獲取觸摸點在view中的位置
self.currentPoint = point;
for (GesturePasswordButton *btn in self.subviews) {
if (CGRectContainsPoint(btn.frame, point)) {//判斷觸摸點是否在當(dāng)前btn的范圍之內(nèi)
[btn setSelected:YES];
if (![self.selectorAry containsObject:btn]) {
[self.selectorAry addObject:btn];
[self setPropertiesByState:GesturePasswordButtonStateSelected];//改變該btn的狀態(tài)
}
}
}
[self setNeedsDisplay];//重繪view來畫線
}
- touchesMoved方法
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
self.currentPoint = point;
for (GesturePasswordButton *btn in self.subviews) {
if (CGRectContainsPoint(btn.frame, point)) {
[btn setSelected:YES];
if (![self.selectorAry containsObject:btn]) {
[self.selectorAry addObject:btn];
[self setPropertiesByState:GesturePasswordButtonStateSelected];
}
}
}
[self setNeedsDisplay];
}
- touchesEnded方法
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
GesturePasswordButton *btn = [self.selectorAry lastObject];
[self setCurrentPoint:btn.center];
[self setNeedsDisplay];
}
- 調(diào)用drawRect方法 重繪view
- (void)drawRect:(CGRect)rect{
[super drawRect:rect];
if ([self.selectorAry count] == 0) {
return;
}
UIBezierPath *path = [UIBezierPath bezierPath];
[path setLineWidth:self.lineWidth];
[self.lineColor set];
[path setLineJoinStyle:kCGLineJoinRound];
[path setLineCapStyle:kCGLineCapRound];
for (NSInteger i = 0; i < self.selectorAry.count; i ++) {
GesturePasswordButton *btn = self.selectorAry[i];
if (i == 0) {
[path moveToPoint:[btn center]];
}else{
[path addLineToPoint:[btn center]];
}
[btn setNeedsDisplay];
}
[path addLineToPoint:self.currentPoint];
[path stroke];
}
- 為了實現(xiàn)當(dāng)用戶輸入錯誤后宪肖,不正確狀態(tài)顯示0.5秒后恢復(fù)為正常狀態(tài)表制,需要在上面實現(xiàn)的setPropertiesByState方法中加入如下代碼,另外實現(xiàn)resetButtons和lockState方法
case GesturePasswordButtonStateNormal:
[self setUserInteractionEnabled:YES];\\設(shè)置當(dāng)前用戶可以進行觸摸操作
[self resetButtons];
self.fillCenterPoint = YES;
case GesturePasswordButtonStateIncorrect:
[self setUserInteractionEnabled:NO];\\設(shè)置當(dāng)前用戶不可進行觸摸操作
self.fillCenterPoint = YES;
self.showCenterPoint = YES;
self.strokeWidth = 1.f;
self.centerPointRadius = 10.f;
self.lineWidth = 2.f;
self.lineColor = [UIColor orangeColor];
self.fillColor = RGBA(255, 245, 238, 1);
self.strokeColor = RGBA(255, 245, 238, 1);
self.centerPointColor = [UIColor orangeColor];
[self performSelector:@selector(lockState:) withObject:[NSArray arrayWithObject:[NSNumber numberWithInteger:GesturePasswordButtonStateNormal]] afterDelay:0.5f];\\0.5秒后執(zhí)行l(wèi)ockState方法
\\重置selectorAry數(shù)組
- (void)resetButtons {
for (NSInteger i=0; i<[self.selectorAry count]; i++) {
GesturePasswordButton *button = self.selectorAry[i];
[button setSelected:NO];
}
[self.selectorAry removeAllObjects];
[self setNeedsDisplay];
}
\\切換btn狀態(tài)
- (void)lockState:(NSArray *)states {
NSNumber *stateNumber = [states objectAtIndex:0];
[self setPropertiesByState:[stateNumber integerValue]];
}
四控乾、調(diào)用GesturePasswordView
現(xiàn)在我們要明確一下這個GesturePasswordView主要用于手勢登錄么介、設(shè)置手勢密碼纫事、重置手勢密碼這三種情況底靠。那么在GesturePasswordViewController.h中可以創(chuàng)建一個枚舉類型。
typedef NS_ENUM(NSInteger, GesturePasswordStatus) {
GesturePasswordStatusSet = 0,\\設(shè)置
GesturePasswordStatusReset = 1,\\重置
GesturePasswordStatusLogin = 2,\\登錄
};
登錄雁社、設(shè)置、重置三種狀態(tài)下的流程圖
根據(jù)流程圖我們可以在GesturePasswordView.h中創(chuàng)建六種類型的Block方法
@property (nonatomic, copy) void(^verificationPassword)();//驗證舊密碼正確
@property (nonatomic, copy) void(^verificationError)();//驗證舊密碼錯誤
@property (nonatomic, copy) void(^onPasswordSet)();//第一次輸入密碼
@property (nonatomic, copy) void(^onGetCorrectPswd)();//第二次輸入密碼且和第一次一樣
@property (nonatomic, copy) void(^onGetIncorrectPswd)();//第二次輸入密碼且和第一次不一樣
@property (nonatomic, copy) void(^errorInput)();//手勢密碼小于四位數(shù)
根據(jù)三種狀態(tài)我們可以在GesturePasswordView.h中創(chuàng)建三種初始化方法
+(instancetype)status:(GesturePasswordStatus)status frame:(CGRect)frame onGetCorrectPswd:(void (^)())GetCorrectPswd onGetIncorrectPswd:(void (^)())GetIncorrectPswd errorInput:(void (^)())errorInput;//用于登錄
+(instancetype)status:(GesturePasswordStatus)status frame:(CGRect)frame onPasswordSet:(void (^)())onPasswordSet onGetCorrectPswd:(void (^)())GetCorrectPswd onGetIncorrectPswd:(void (^)())GetIncorrectPswd errorInput:(void (^)())errorInput;//用于設(shè)置
+(instancetype)status:(GesturePasswordStatus)status frame:(CGRect)frame verificationPassword:(void (^)())verificationPassword verificationError:(void (^)())verificationError onPasswordSet:(void (^)())onPasswordSet onGetCorrectPswd:(void (^)())GetCorrectPswd onGetIncorrectPswd:(void (^)())GetIncorrectPswd errorInput:(void (^)())errorInput;//用于重置
在GesturePasswordView.m中實現(xiàn)這三種方法
+(instancetype)status:(GesturePasswordStatus)status frame:(CGRect)frame onGetCorrectPswd:(void (^)())GetCorrectPswd onGetIncorrectPswd:(void (^)())GetIncorrectPswd errorInput:(void (^)())errorInput
{
return [self status:status frame:frame onPasswordSet:nil onGetCorrectPswd:GetCorrectPswd onGetIncorrectPswd:GetIncorrectPswd errorInput:errorInput];
}
+(instancetype)status:(GesturePasswordStatus)status frame:(CGRect)frame onPasswordSet:(void (^)())onPasswordSet onGetCorrectPswd:(void (^)())GetCorrectPswd onGetIncorrectPswd:(void (^)())GetIncorrectPswd errorInput:(void (^)())errorInput
{
return [self status:status frame:frame verificationPassword:nil verificationError:nil onPasswordSet:onPasswordSet onGetCorrectPswd:GetCorrectPswd onGetIncorrectPswd:GetIncorrectPswd errorInput:errorInput];
}
+(instancetype)status:(GesturePasswordStatus)status frame:(CGRect)frame verificationPassword:(void (^)())verificationPassword verificationError:(void (^)())verificationError onPasswordSet:(void (^)())onPasswordSet onGetCorrectPswd:(void (^)())GetCorrectPswd onGetIncorrectPswd:(void (^)())GetIncorrectPswd errorInput:(void (^)())errorInput
{
GesturePasswordView *gesView = [[GesturePasswordView alloc] initWithFrame:frame];
gesView.status = status;
gesView.verificationPassword = verificationPassword;
gesView.verificationError = verificationError;
gesView.onPasswordSet = onPasswordSet;
gesView.onGetCorrectPswd = GetCorrectPswd;
gesView.onGetIncorrectPswd = GetIncorrectPswd;
gesView.errorInput = errorInput;
return gesView;
}
在touchesEnded方法中久脯,我們可以根據(jù)當(dāng)前出入哪種狀態(tài)做出相應(yīng)的處理蒜绽,所以touchesEnded方法應(yīng)該是這樣的:
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
if (self.selectorAry.count < 4) {
self.errorInput();
[self setPropertiesByState:GesturePasswordButtonStateNormal];
}else if (self.status == GesturePasswordStatusSet) {
[self setPasswordBlock];
}else if(self.status == GesturePasswordStatusReset){
NSString *password = [self getPassword];
NSString *inputPassword = [[NSString alloc] init];
if (self.resetInputNum == 0) {
for (GesturePasswordButton *btn in self.selectorAry) {
inputPassword = [inputPassword stringByAppendingFormat:@"%@",@(btn.tag)];
}
if ([inputPassword isEqualToString:password]) {
self.verificationPassword();
self.resetInputNum += 1;
[self performSelector:@selector(lockState:) withObject:[NSArray arrayWithObject:[NSNumber numberWithInteger:GesturePasswordButtonStateNormal]] afterDelay:0.3f];
}else{
self.verificationError();
[self setPropertiesByState:GesturePasswordButtonStateIncorrect];
}
}else if(self.resetInputNum == 1){
[self setPasswordBlock];
}
}else if(self.status == GesturePasswordStatusLogin){
NSString *password = [self getPassword];
NSString *inputPassword = [[NSString alloc] init];
for (GesturePasswordButton *btn in self.selectorAry) {
inputPassword = [inputPassword stringByAppendingFormat:@"%@",@(btn.tag)];
}
if ([inputPassword isEqualToString:password]) {
self.onGetCorrectPswd();
[self setPropertiesByState:GesturePasswordButtonStateNormal];
}else{
self.onGetIncorrectPswd();
[self setPropertiesByState:GesturePasswordButtonStateIncorrect];
}
}
GesturePasswordButton *btn = [self.selectorAry lastObject];
[self setCurrentPoint:btn.center];
[self setNeedsDisplay];
}
- (void)setPasswordBlock
{
if (self.inputNum == 0) {
self.firstPassword = [[NSString alloc] init];
for (GesturePasswordButton *btn in self.selectorAry) {
self.firstPassword = [self.firstPassword stringByAppendingFormat:@"%@",@(btn.tag)];
}
self.onPasswordSet();
self.inputNum += 1;
[self performSelector:@selector(lockState:) withObject:[NSArray arrayWithObject:[NSNumber numberWithInteger:GesturePasswordButtonStateNormal]] afterDelay:0.3f];
}else{
NSString *secondPassword = [[NSString alloc] init];
for (GesturePasswordButton *btn in self.selectorAry) {
secondPassword = [secondPassword stringByAppendingFormat:@"%@",@(btn.tag)];
}
if ([self.firstPassword isEqualToString:secondPassword]) {
[self savePassWord:secondPassword];
self.onGetCorrectPswd();
[self performSelector:@selector(lockState:) withObject:[NSArray arrayWithObject:[NSNumber numberWithInteger:GesturePasswordButtonStateNormal]] afterDelay:0.3f];
}else{
self.onGetIncorrectPswd();
[self setPropertiesByState:GesturePasswordButtonStateIncorrect];
self.inputNum -= 1;
}
}
}
存取密碼的方法
- (void)savePassWord:(NSString *)password
{
NSUserDefaults *userdefault = [NSUserDefaults standardUserDefaults];
[userdefault setObject:@{@"password":password} forKey:GESTUREPASSWORD];
[userdefault synchronize];
}
- (NSString *)getPassword
{
NSDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:GESTUREPASSWORD];
return [dic objectForKey:@"password"];
}
在GesturePasswordViewController.h這樣調(diào)用
if (self.status == GesturePasswordStatusSet) {
self.infoLabel.text = @"請設(shè)置手勢密碼";
GesturePasswordView *view = [GesturePasswordView status:GesturePasswordStatusSet frame:CGRectMake(0, 200, SCREEN_WIDTH, 400) onPasswordSet:^() {
self.infoLabel.text = @"請重新輸入剛才設(shè)置的手勢密碼";
} onGetCorrectPswd:^ {
self.infoLabel.text = @"設(shè)置成功";
[weakSelf setGesturePasswordSwitchOpen];
} onGetIncorrectPswd:^ {
self.infoLabel.text = @"與上一次輸入不一致,請重新設(shè)置";
} errorInput:^{
self.infoLabel.text = @"請至少連接4個點";
}];
[self.view addSubview:view];
}else if (self.status == GesturePasswordStatusReset){
self.infoLabel.text = @"請驗證舊密碼";
GesturePasswordView *view = [GesturePasswordView status:GesturePasswordStatusReset frame:CGRectMake(0, 200, SCREEN_WIDTH, 400) verificationPassword:^{
self.infoLabel.text = @"請輸入新的手勢密碼";
} verificationError:^{
self.infoLabel.text = @"舊密碼驗證錯誤";
} onPasswordSet:^ {
self.infoLabel.text = @"請重新輸入剛才設(shè)置的手勢密碼";
} onGetCorrectPswd:^ {
self.infoLabel.text = @"設(shè)置成功";
[weakSelf setGesturePasswordSwitchOpen];
} onGetIncorrectPswd:^ {
self.infoLabel.text = @"與上一次輸入不一致桶现,請重新設(shè)置";
} errorInput:^{
self.infoLabel.text = @"請至少連接4個點";
}];
[self.view addSubview:view];
}else if (self.status == GesturePasswordStatusLogin){
self.infoLabel.text = @"請輸入手勢密碼";
GesturePasswordView *view = [GesturePasswordView status:GesturePasswordStatusLogin frame:CGRectMake(0, 200, SCREEN_WIDTH, 400) onGetCorrectPswd:^ {
self.infoLabel.text = @"解鎖成功";
[self loginSuccess];
} onGetIncorrectPswd:^ {
self.infoLabel.text = @"密碼錯誤,請重新輸入";
} errorInput:^{
self.infoLabel.text = @"請至少連接4個點";
}];
[self.view addSubview:view];
}
結(jié)束語
整個思路大致就是這樣的鼎姊,主體實現(xiàn)的代碼已經(jīng)在文章中寫出來了骡和,當(dāng)然還有手勢密碼鎖的開啟與關(guān)閉等一些細節(jié)代碼沒有寫出,如果需要完整代碼的可以前往github下載Demo相寇。如果有什么不對的地方慰于,希望大家可以及時的指出,謝謝;缴馈F旁!