标签:ios ios开发 ios仿支付宝手势 ios仿支付宝手势解锁 ios手势解锁
呀~,这么快就转到ios阵营了???,android还有那么多坑呢???为此我也只能啃着馒头留下屈辱的眼泪了。。
本次由于开发公司产品的android版,继而ios版也负责一部分,其中一部分就是手势解锁的问题(为了要与android版一致,也算是非了一部分心血)
然而,但我打开iPhone,发现支付宝客户端已经没有手势解锁了,取而代之的时指纹解锁,关于指纹解锁,暂时还来不及研究,只能以后有机会再说了。。。
当然,支付宝android目前还是手势解锁,所以也是为了与之对应(ios版现在只能借鉴其android版了)
不多说了。。。。
1.资源
https://github.com/nsdictionary/CoreLock
上面的连接是一位大神已经写好的一个高仿支付宝手势解锁的项目,本来也可以说完全不用看我这篇文章就直接拿去用了,然而有些地方还是要改动一下的,毕竟是高仿嘛
此次具体的目的,如果你有android版支付宝客户端,请到‘手势’这一功能看一看效果。
效果:
1.手势未开启时的界面:
2.点击滑块后的跳转界面:
3.第一次绘制结束后的界面(由于线条消失的比较快,并没有截到):
4.两次绘制完成之后的界面:
看到这里如果你发现跟你的应用场景并不相同,下面的可以不用看了。
另,本文也不会提供代码下载,因为只是在这位大神的代码基础上做了自己的改动而已。
关于手势密码这一界面的设计,这里也不做提供,提供思路:
1.判断本地手势密码是否开启,根据开启标志,返回tableview的不同section和row,用以隐藏和显示界面中的各元素
2.手势密码的滑块和修改手势密码的点击,可以设置不同的标志,在跳转后的界面中进行判断来显示不同的东西。
顺序:
手势密码界面->点击滑块或修改手势密码(没有设置情况下是隐藏)->设置手势密码界面
设置手势密码这一个界面,我是在storyboard中拉了一个viewcontroller来搞的,如果你有其他方法都行,下面是这个界面的主要代码:
// // GestureSetupViewController.m // yktapp // // Created by Shuwei on 15/6/29. // Copyright (c) 2015年 All rights reserved. // #import "GestureSetupViewController.h" #import "CoreLockConst.h" #import "CoreArchive.h" #import "CLLockLabel.h" #import "CLLockNavVC.h" #import "CLLockView.h" #import "CLLockInfoView.h" #import "SWTool.h" #import "SWProperties.h" #import "CommonData.h" #import "TextDialog.h" #import "MBProgressHUD.h" #import "SWCallWebservice.h" #import "RetCodeMessageBean.h" @interface GestureSetupViewController () //@property (weak, nonatomic) IBOutlet GestureView *gestureView; @property (nonatomic,strong) CLLockView * gestureLockView; @property (nonatomic,strong) CLLockLabel * hintLlabel; @property (nonatomic,strong) CLLockInfoView * topInforView; @property (nonatomic,strong) IBOutlet UIBarButtonItem *resetBtn; @end @implementation GestureSetupViewController{ SWProperties *prop; UIButton *checkLoginBtn; CoreLockType type; NSInteger tryCnt; NSInteger loginCnt; UITextField *passTxt; TextDialog *payDialog; MBProgressHUD *hud; } @synthesize hintLlabel; @synthesize gestureLockView; @synthesize topInforView; @synthesize resetBtn; - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor=CoreLockViewBgColor; prop = [SWProperties sharedInstance]; NSString *temp = [prop getValuebyFieldName:@"gestureTryCnt"]; if([SWTool isEmptyString:temp]){ tryCnt = 5; }else{ tryCnt = temp.integerValue; } temp = [prop getValuebyFieldName:@"gestureLoginCnt"]; if([SWTool isEmptyString:temp]){ loginCnt = 3; }else{ loginCnt = temp.integerValue; } hud = [[MBProgressHUD alloc] initWithView:self.view]; [self initView]; resetBtn = [[UIBarButtonItem alloc]init]; resetBtn.title = @"重设"; [resetBtn setTintColor:[UIColor whiteColor]]; } -(void)initView{ for (UIView * subview in [self.view subviews]) { [subview removeFromSuperview]; } CGRect frame= [UIScreen mainScreen].applicationFrame; CGRect gest = frame; CGFloat top=0; if([[CommonData shareInstance].setFlag isEqualToString:@"0"]){ gest = frame; gest.size.height=44; gest.size.width=44; gest.origin.x = self.view.center.x-22; gest.origin.y +=80; topInforView = [[CLLockInfoView alloc] initWithFrame:gest]; topInforView.backgroundColor = CoreLockViewBgColor; [self.view addSubview:topInforView]; top = 130; type = CoreLockTypeSetPwd; self.title=@"设置手势密码"; }else{ top = 80; gest = frame; gest.origin.y = frame.size.height-50; gest.size.height=44; gest.size.width=150; gest.origin.x = self.view.center.x-75; checkLoginBtn = [[UIButton alloc] initWithFrame:gest]; [checkLoginBtn setTitle:@"验证登录密码" forState:UIControlStateNormal]; [checkLoginBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [checkLoginBtn setTintColor:[UIColor whiteColor]]; checkLoginBtn.titleLabel.font = [UIFont systemFontOfSize: 16]; [checkLoginBtn addTarget:self action:@selector(checkLogin:) forControlEvents:UIControlEventTouchDown]; [self.view addSubview:checkLoginBtn]; type = CoreLockTypeVeryfiPwd; self.title=@"验证手势密码"; } gest = frame; gest.size.height=31; gest.origin.y +=top; hintLlabel = [[CLLockLabel alloc] initWithFrame:gest]; hintLlabel.textAlignment = NSTextAlignmentCenter; [self.view addSubview:hintLlabel]; if([[CommonData shareInstance].setFlag isEqualToString:@"0"]){ [self.hintLlabel showNormalMsg:@"绘制解锁图案"]; }else{ [self.hintLlabel showNormalMsg:@"请输入原手势密码"]; } gest = frame; top +=60; gest.size.height =frame.size.height/2+20; gest.origin.y +=top; gestureLockView = [[CLLockView alloc] initWithFrame:gest]; gestureLockView.backgroundColor = CoreLockViewBgColor; gestureLockView.type = type; gestureLockView.needLine = YES; [self.view addSubview:gestureLockView]; [self event]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)resetBtn:(id)sender { self.navigationItem.rightBarButtonItem=nil; self.topInforView.success=NO; self.topInforView.pwd = nil; [self.topInforView setNeedsDisplay]; [self.hintLlabel showNormalMsg:@"绘制解锁图案"]; [self.gestureLockView resetPwd]; } -(void)resetView{ } -(IBAction)checkLogin:(id)sender{ payDialog = [[TextDialog alloc] initWithTitle:@"请输入登录密码" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定" ,nil]; passTxt = [[UITextField alloc] init]; passTxt.frame = CGRectMake(0, 0, 0, 40); passTxt.placeholder=@"请输入登录密码"; passTxt.delegate = self; passTxt.borderStyle = UITextBorderStyleRoundedRect; [passTxt setSecureTextEntry:YES]; passTxt.returnKeyType = UIReturnKeyDone; [payDialog addCustomerSubview:passTxt]; passTxt.text=@""; [passTxt becomeFirstResponder]; [payDialog notifayBtnStatus:NO]; [payDialog show]; } -(void)event{ /* * 设置密码 */ /** 开始输入:确认 */ self.gestureLockView.setPWConfirmlock = ^(){ [hintLlabel showNormalMsg:CoreLockPWDTitleConfirm]; }; /** 密码长度不够 */ self.gestureLockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){ [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"最少链接%@个点,请重新输入",@(CoreLockMinItemCount)]]; }; /** 两次密码不一致 */ self.gestureLockView.setPWSErrorTwiceDiffBlock = ^(NSString *pwd1,NSString *pwdNow){ [self.hintLlabel showWarnMsg:CoreLockPWDDiffTitle]; //self.navigationItem.rightBarButtonItem = self.resetItem; }; /** 第一次输入密码:正确 */ self.gestureLockView.setPWFirstRightBlock = ^(NSString *pwdM){ NSLog(@"first pwd=%@",pwdM); self.topInforView.success=YES; self.topInforView.pwd = pwdM; [self.topInforView setNeedsDisplay]; self.navigationItem.rightBarButtonItem=resetBtn; self.navigationItem.rightBarButtonItem.action = @selector(resetBtn:); self.navigationItem.rightBarButtonItem.target = self; [self.hintLlabel showNormalMsg:CoreLockPWDTitleConfirm]; }; /** 再次输入密码一致 */ self.gestureLockView.setPWTwiceSameBlock = ^(NSString *pwd){ NSLog(@"pwd==%@",pwd); [self.hintLlabel showNormalMsg:CoreLockPWSuccessTitle]; self.navigationItem.rightBarButtonItem=nil; //存储密码 //[CoreArchive setStr:pwd key:CoreLockPWDKey]; if([prop openUserDB]){ [prop writeValueByFieldName:@"gestureFlag" withValue:@"1"]; [prop writeValueByFieldName:@"gesturePwd" withValue:[SWTool toMD5:pwd]]; [prop writeValueByFieldName:@"gestureLine" withValue:@"1"]; [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"]; } //禁用交互 self.view.userInteractionEnabled = NO; [self performSelector:@selector(dismis) withObject:nil afterDelay:0.5]; }; /** 验证 */ self.gestureLockView.verifyPwdBlock = ^(NSString *pwd){ NSLog(@"verifyPwdBlock.pwd==%@",pwd); NSString *local = [prop getValuebyFieldName:@"gesturePwd"]; if([SWTool isEmptyString:local]){ [self.hintLlabel showWarnMsg:@"密码获取失败了,请您登录系统"]; [self clearDB]; [CommonData shareInstance].needBack = NO; [prop writeValueByFieldName:@"devicetoken" withValue:nil]; [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.5]; }else{ tryCnt--; if([[SWTool toMD5:pwd] isEqualToString:local]){ [self doSuccess]; }else{ if(tryCnt<=0){ [self clearDB]; [prop writeValueByFieldName:@"devicetoken" withValue:nil]; [self.hintLlabel showWarnMsg:@"手势密码不正确,请您重新登录系统!"]; [CommonData shareInstance].needBack = NO; [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.5]; }else{ [prop writeValueByFieldName:@"gestureTryCnt" withValue:[NSString stringWithFormat:@"%ld",tryCnt]]; [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"密码错了,还有%ld次机会",tryCnt]]; } } } return YES; }; } -(void)doSuccess{ if([[CommonData shareInstance].setFlag isEqualToString:@"1"]){ [self.hintLlabel showNormalMsg:CoreLockVerifySuccesslTitle]; if([prop openUserDB]){ [self clearDB]; } self.view.userInteractionEnabled = NO; [self performSelector:@selector(dismis) withObject:nil afterDelay:0.5]; }else if([[CommonData shareInstance].setFlag isEqualToString:@"2"]){ [CommonData shareInstance].setFlag = @"0"; [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"]; [self initView]; } } -(void)toLogin{ [self performSegueWithIdentifier:@"toLogin" sender:self]; } -(void)clearDB{ [prop writeValueByFieldName:@"gestureFlag" withValue:@"0"]; [prop writeValueByFieldName:@"gesturePwd" withValue:nil]; [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"]; [prop writeValueByFieldName:@"gestureLoginCnt" withValue:@"3"]; } -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if(alertView.tag==12){ if(buttonIndex==0){ [self clearDB]; [self performSegueWithIdentifier:@"toLogin" sender:self]; } }else if(buttonIndex==9000){ [self doCheckLogin]; }else if(alertView.tag==11){ [self checkLogin:nil]; } } -(void)willPresentPayAlertView:(UIView *)alertView{ [passTxt becomeFirstResponder]; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if(textField==passTxt){ if ([string length]>0){ [payDialog notifayBtnStatus:YES]; }else{ [payDialog notifayBtnStatus:NO]; } } return YES; } - (void)textFieldDidChange:(UITextField *)textField { if(textField==passTxt){ if(textField.text.length>0){ [payDialog notifayBtnStatus:YES]; }else { [payDialog notifayBtnStatus:NO]; } } } -(BOOL)textFieldShouldReturn:(UITextField *)textField{ if(textField.text.length==0){ [passTxt resignFirstResponder]; }else{ [payDialog removeFromSuperview]; [self doCheckLogin]; } return YES; } -(void)doCheckLogin{ [passTxt resignFirstResponder]; [SWTool showHUD:@"正在验证" andView:self.view andHUD:hud]; NSString *userid = [prop getValuebyFieldName:@"sno"]; [SWCallWebservice doCheckLoginWithUserid:userid andPwd:passTxt.text andSuccess:^(NSArray *_ret) { [hud hide:YES]; if(_ret&&[_ret count]>0){ loginCnt--; RetCodeMessageBean *bean = [_ret objectAtIndex:0]; if([bean.retcode isEqualToString:@"0"]){ [self doSuccess]; }else{ if(loginCnt<=0){ [SWTool showMessageWithOkButton:@"验证失败了,请重新登录系统" andDelegate:self]; }else{ [prop writeValueByFieldName:@"gestureLoginCnt" withValue:[NSString stringWithFormat:@"^%ld",loginCnt]]; [SWTool showMessageWithCancelAndOkButton:[NSString stringWithFormat:@"密码错误,还有%ld次机会",loginCnt] andTag:11 andDelegate:self andCancelMsg:@"取消" andOkMsg:@"再试一次"]; } } }else{ [SWTool showMessageWithOkButton:@"请求失败了,请稍后再试"]; } } andErrBack:^(NSInteger code) { [hud hide:YES]; if(code==0){ [SWTool showMessageWithOkButton:@"请求超时了,请稍后再试"]; }else if(code==401){ [CommonData shareInstance].needBack = YES; [SWTool showMessage:@"用户认证已过期,请重新登录" seconds:1]; [self performSegueWithIdentifier:@"toLogin" sender:self]; }else{ [SWTool showMessageWithOkButton:@"请求失败了,请稍后再试"]; } }]; } -(void)dismis{ [self performSegueWithIdentifier:@"exitToMng" sender:self]; } @end
回到,上面的代码中,可以看到,头部引入了很多东西,由于是完整的内容,这里对于我来说都是必须的,这里讲解一下
"CommonData.h" 这个类(不可少,下面的其他类暂时都可以不要)主要做数据共享,主要是判断setFlag的标志显示不同的界面内容的,可以看到主要有,0,1,2三个标志,0代表未设置手势密码,这种情况下要绘制2次,1,代表的时设置过手势密码,但是要关闭这个手势,这是就要验证手势,见下图:
2代表的是,点击修改的标志,这个逻辑是先验证,然后在重新绘制新的手势,这个过程有3步,主要验证->绘制第一次->绘制第二次。
"SWProperties.h" 主要是我的本地sqlitedb的操作,用于保存手势密码设置未设置的标志,这里不做详细说明,如果你不保存可以不需要
"SWTool.h" 主要是一些工具类,这里主要用到 空字符串的判断,请自己查找
"TextDialog.h"是点击验证登录密码时的弹出框,请自己找,效果:
"MBProgressHUD.h"这个不用说了吧,验证的时候肯定要花费时间的,一个等待的提示,不可少
"SWCallWebservice.h"封装的验证登录密码的类
"RetCodeMessageBean.h"验证登录返回后的对象
由于我没有把demo中的 CLLockVC相关类copy过来,所以有些改动,首先把:
typedef enum{ //设置密码 CoreLockTypeSetPwd=0, //输入并验证密码 CoreLockTypeVeryfiPwd, //修改密码 CoreLockTypeModifyPwd, }CoreLockType;
@property (nonatomic,assign) BOOL needLine;
再把这个类中的方法添加一个参数
@property (nonatomic,copy) void (^setPWFirstRightBlock)(NSString *pwd);
if(_setPWFirstRightBlock != nil) _setPWFirstRightBlock(self.pwdM);
-(void)itemHandel:(CLLockItemView *)itemView{ //选中 if(self.needLine){ itemView.selected = YES; }else{ itemView.selected = NO; } itemView.need = self.needLine; //绘制 [self setNeedsDisplay]; }
修改 CLLockInfoView.h
@property (nonatomic,assign) BOOL success; @property (nonatomic,copy) NSString *pwd;
这个主要是用于绘制的时候,头部的小图标里面的小圆圈也对应改变而已。
// // CLLockInfoView.m // CoreLock // // Created by 成林 on 15/4/27. // Copyright (c) 2015年 冯成林. All rights reserved. // #import "CLLockInfoView.h" #import "CoreLockConst.h" @implementation CLLockInfoView @synthesize success; @synthesize pwd; -(void)drawRect:(CGRect)rect{ //获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //设置属性 CGContextSetLineWidth(ctx, CoreLockArcLineW); //设置线条颜色 [CoreLockCircleLineNormalColor set]; //新建路径 CGMutablePathRef pathM =CGPathCreateMutable(); CGFloat marginV = 3.f; CGFloat padding = 1.0f; CGFloat rectWH = (rect.size.width - marginV * 2 - padding*2) / 3; //添加圆形路径 for (NSUInteger i=0; i<9; i++) { NSUInteger row = i % 3; NSUInteger col = i / 3; CGFloat rectX = (rectWH + marginV) * row + padding; CGFloat rectY = (rectWH + marginV) * col + padding; CGRect rect = CGRectMake(rectX, rectY, rectWH, rectWH); if(success&&pwd){ if ([pwd rangeOfString:[NSString stringWithFormat:@"%ld",i]].location != NSNotFound) { CGContextSetRGBFillColor(ctx,34/255.f, 178/255.f, 246/255.f,1); CGContextAddEllipseInRect(ctx,rect); //CGPathAddEllipseInRect(pathM, NULL, rect); CGContextFillPath(ctx); }else{ CGPathAddEllipseInRect(pathM, NULL, rect); } }else{ CGPathAddEllipseInRect(pathM, NULL, rect); } } //添加路径 CGContextAddPath(ctx, pathM); //绘制路径 CGContextStrokePath(ctx); //释放路径 CGPathRelease(pathM); } @end
到此,对于demo的修改已基本结束,不得不说,这位大神的demo非常强大
下面是关于如何启动或跳转到手势解锁界面的
说明一下,我的启动画面是自己做的,并没有用系统提供的launchScreen
所以,登录跳转还是比较方便,在启动画面的controller里面判断如果设置了手势,就跳转到手势登录界面,手势登录效果图:
代码也很简单,在storyboard中拉一个viewcontroller,选择好我们的手势登录类就行了:
// // GestureLoginViewController.m // // // Created by job on 15/6/29. // Copyright (c) 2015年. All rights reserved. // #import "GestureLoginViewController.h" #import "SWTool.h" #import "CoreLockConst.h" #import "CoreArchive.h" #import "CLLockLabel.h" #import "CLLockNavVC.h" #import "CLLockView.h" #import "CLLockInfoView.h" #import "SWProperties.h" #import "CommonData.h" @interface GestureLoginViewController () @property (nonatomic,strong) CLLockView * gestureLockView; @property (nonatomic,strong) CLLockLabel * hintLlabel; @end @implementation GestureLoginViewController{ SWProperties *prop; UIButton *checkLoginBtn; CoreLockType type; NSInteger tryCnt; NSInteger loginCnt; UIImageView *logo; UILabel *usernoLabel; NSString *gestureLine; } @synthesize gestureLockView; @synthesize hintLlabel; - (void)viewDidLoad { [super viewDidLoad]; type = CoreLockTypeVeryfiPwd; self.view.backgroundColor=CoreLockViewBgColor; prop = [SWProperties sharedInstance]; gestureLine = [prop getValuebyFieldName:@"gestureLine"]; NSString *temp = [prop getValuebyFieldName:@"gestureTryCnt"]; if([SWTool isEmptyString:temp]){ tryCnt = 5; }else{ tryCnt = temp.integerValue; } [self initView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } -(void)initView{ for (UIView * subview in [self.view subviews]) { [subview removeFromSuperview]; } CGRect frame= [UIScreen mainScreen].applicationFrame; CGRect gest = frame; CGFloat top=60; logo = [[UIImageView alloc] initWithFrame:CGRectMake((frame.size.width-70)/2, top, 70, 70)]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_header.jpg",prop.gid]]; UIImage *theImage = [UIImage imageWithContentsOfFile:filePath]; if(!theImage){ theImage =[UIImage imageNamed:@"ic_head.png"]; } logo.image = theImage; [logo.layer setCornerRadius:(35)]; [logo.layer setMasksToBounds:YES]; [self.view addSubview:logo]; top = 135; usernoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, top, frame.size.width, 12)]; usernoLabel.textAlignment=NSTextAlignmentCenter; usernoLabel.font = [UIFont systemFontOfSize: 10]; usernoLabel.hidden=YES; usernoLabel.textColor = [UIColor whiteColor]; NSString *temp = [prop getValuebyFieldName:@"sno"]; usernoLabel.text = temp; [self.view addSubview:usernoLabel]; top = 130; gest = frame; gest.size.height=22; gest.origin.y +=top; hintLlabel = [[CLLockLabel alloc] initWithFrame:gest]; hintLlabel.textAlignment = NSTextAlignmentCenter; [self.view addSubview:hintLlabel]; gest = frame; top +=22; gest.size.height =gest.size.height/2+10; gest.origin.y +=top; gestureLockView = [[CLLockView alloc] initWithFrame:gest]; gestureLockView.backgroundColor = CoreLockViewBgColor; gestureLockView.type = type; if(![SWTool isEmptyString:gestureLine]&&[gestureLine isEqualToString:@"0"]){ gestureLockView.needLine = NO; }else{ gestureLockView.needLine = YES; } [self.view addSubview:gestureLockView]; gest = frame; gest.origin.y = gestureLockView.frame.origin.y+gestureLockView.frame.size.height+20; gest.size.height=44; gest.size.width=100; gest.origin.x = frame.size.width-135;; checkLoginBtn = [[UIButton alloc] initWithFrame:gest]; [checkLoginBtn setTitle:@"其他方式登录" forState:UIControlStateNormal]; [checkLoginBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [checkLoginBtn setTintColor:[UIColor whiteColor]]; [checkLoginBtn addTarget:self action:@selector(otherLogin:) forControlEvents:UIControlEventTouchDown]; checkLoginBtn.titleLabel.font = [UIFont systemFontOfSize: 15]; [self.view addSubview:checkLoginBtn]; [self event]; } -(void)event{ /** 密码长度不够 */ self.gestureLockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){ tryCnt--; usernoLabel.hidden=NO; if(tryCnt<=0){ [self.hintLlabel showWarnMsg:@"密码错了,请您登录系统"]; [self clearDB]; [CommonData shareInstance].needBack = NO; [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.2]; }else{ [prop writeValueByFieldName:@"gestureTryCnt" withValue:[NSString stringWithFormat:@"%ld",tryCnt]]; [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"密码错了,还有%ld次机会",tryCnt]]; } }; /** 验证 */ self.gestureLockView.verifyPwdBlock = ^(NSString *pwd){ NSLog(@"verifyPwdBlock.pwd==%@",pwd); NSString *local = [prop getValuebyFieldName:@"gesturePwd"]; if([SWTool isEmptyString:local]){ [self.hintLlabel showWarnMsg:@"密码获取失败了,请您登录系统"]; [self clearDB]; [CommonData shareInstance].needBack = NO; [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.5]; }else{ tryCnt--; if([[SWTool toMD5:pwd] isEqualToString:local]){ //todo login [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"0"]; if([CommonData shareInstance].needFinish){ [self dismissViewControllerAnimated:YES completion:nil]; }else{ [self performSegueWithIdentifier:@"toMain" sender:self]; } [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"]; }else{ usernoLabel.hidden=NO; if(tryCnt<=0){ [self.hintLlabel showWarnMsg:@"密码错了,请您登录系统"]; [self clearDB]; [CommonData shareInstance].needBack = NO; [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.2]; }else{ [prop writeValueByFieldName:@"gestureTryCnt" withValue:[NSString stringWithFormat:@"%ld",tryCnt]]; [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"密码错了,还有%ld次机会",tryCnt]]; } } } return YES; }; } -(void)toLogin{ [self performSegueWithIdentifier:@"toLogin" sender:self]; } -(void)clearDB{ [prop writeValueByFieldName:@"gestureFlag" withValue:@"0"]; [prop writeValueByFieldName:@"gesturePwd" withValue:nil]; [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"]; [prop writeValueByFieldName:@"devicetoken" withValue:nil]; [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"0"]; } -(IBAction)otherLogin:(id)sender{ [prop writeValueByFieldName:@"devicetoken" withValue:nil]; [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"0"]; [CommonData shareInstance].needBack = NO; [self performSegueWithIdentifier:@"toLogin" sender:self]; } @end
代码相对较少,相信大家经过设置手势功能后,这里也肯定没问题。
最后是其他跳转了,
现在的主要逻辑是,app缓存到后台之后5分钟,我就会跳转到手势锁屏,其他情况,暂时没考虑。
所以我在AppDelegate.m中的applicationDidEnterBackground和applicationWillEnterForeground中做了简单的事情,代码如下:
- (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"mark3"); NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0]; NSString *isShowed = [prop getValuebyFieldName:@"pub.gestureShowed"]; if([SWTool isEmptyString:isShowed]||[isShowed isEqualToString:@"0"]){ timer=[date timeIntervalSince1970]; } } - (void)applicationWillEnterForeground:(UIApplication *)application { NSString *gesturePwd = [prop getValuebyFieldName:@"gesturePwd"]; NSString *gestureFlag = [prop getValuebyFieldName:@"gestureFlag"]; NSString *token = [prop getValuebyFieldName:@"devicetoken"]; if(![SWTool isEmptyString:token]&&![SWTool isEmptyString:gesturePwd]&&![SWTool isEmptyString:gestureFlag]&&[gestureFlag isEqualToString:@"1"]){ NSString *isShowed = [prop getValuebyFieldName:@"pub.gestureShowed"]; if([SWTool isEmptyString:isShowed]||[isShowed isEqualToString:@"0"]){ NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0]; if(!timer){ timer=[dat timeIntervalSince1970]; } NSTimeInterval temp = [dat timeIntervalSince1970]; if((temp-timer)>300){ UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; GestureLoginViewController *gestureLoginViewController = (GestureLoginViewController*)[storyboard instantiateViewControllerWithIdentifier:@"gestureLogin"]; [CommonData shareInstance].needFinish = YES; [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"1"]; UIViewController *topRootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topRootViewController.presentedViewController) { topRootViewController = topRootViewController.presentedViewController; } [topRootViewController presentViewController:gestureLoginViewController animated:YES completion:nil]; } } } }
applicationDidEnterBackground中记录时间,applicationWillEnterForeground根据时间显示手势界面,当然,这里面也有判断是否设置手势,是否已经跳转到手势了等等。
至此,已经完结了,哦对了,手势还有点bug,我发现滑动的适合,两个点之间我稍微的从外面绕一下,就导致中间的点没连上,真是郁闷啊,由于时间比较冲忙,后面我肯定也要解决这个问题的,不过,会不会写下来,就不知道了,提供一下思路,上一个点与下一个点取中间的坐标,判断这个坐标里面是否有按钮,有的情况,判断是否已经添加,没有就加进去。
由于是第一次做ios,而且还是在地铁上花了一个星期不到的时间看着电子书学习ios,然后用1个月的时间完成公司的产品,前面也说过,我是做的android版,然后对应的ios版,也是我来做,时间非常的仓促,很多的地方也有不懂之处,代码写的也比较乱,希望大家不要鄙视。。。。
嘛,就这样愉快的做ios吧,啦啦啦~~~~~~
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:ios ios开发 ios仿支付宝手势 ios仿支付宝手势解锁 ios手势解锁
原文地址:http://blog.csdn.net/joveth/article/details/46696859