呀~。这么快就转到ios阵营了???。android还有那么多坑呢???为此我也仅仅能啃着馒头留下屈辱的眼泪了。

本次因为开发公司产品的android版,继而ios版也负责一部分。当中一部分就是手势解锁的问题(为了要与android版一致,也算是非了一部分心血)

然而。但我打开iPhone,发现支付宝client已经没有手势解锁了,取而代之的时指纹解锁,关于指纹解锁,临时还来不及研究,仅仅能以后有机会再说了。。

当然,支付宝android眼下还是手势解锁,所以也是为了与之相应(ios版如今仅仅能借鉴其android版了)

不多说了。

。。

1.资源

https://github.com/nsdictionary/CoreLock

上面的连接是一位大神已经写好的一个高仿支付宝手势解锁的项目,本来也能够说全然不用看我这篇文章就直接拿去用了,然而有些地方还是要修改一下的。毕竟是高仿嘛

此次详细的目的,假设你有android版支付宝client,请到‘手势’这一功能看一看效果。

效果:

1.手势未开启时的界面:

2.点击滑块后的跳转界面:

3.第一次绘制结束后的界面(因为线条消失的比較快。并没有截到):

4.两次绘制完毕之后的界面:

看到这里假设你发现跟你的应用场景并不同样。以下的能够不用看了。

另,本文也不会提供代码下载。由于仅仅是在这位大神的代码基础上做了自己的修改而已。

关于手势password这一界面的设计,这里也不做提供,提供思路:

1.推断本地手势password是否开启,依据开启标志。返回tableview的不同section和row,用以隐藏和显示界面中的各元素

2.手势password的滑块和改动手势password的点击。能够设置不同的标志,在跳转后的界面中进行推断来显示不同的东西。

顺序:

手势password界面->点击滑块或改动手势password(没有设置情况下是隐藏)->设置手势password界面

设置手势password这一个界面,我是在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=@"设置手势password";
}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:@"验证登录password" 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=@"验证手势password";
} 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:@"请输入原手势password"];
}
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:@"请输入登录password" delegate:self cancelButtonTitle:@"取消"
otherButtonTitles:@"确定" ,nil]; passTxt = [[UITextField alloc] init];
passTxt.frame = CGRectMake(0, 0, 0, 40);
passTxt.placeholder=@"请输入登录password";
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{ /*
* 设置password
*/ /** 開始输入:确认 */
self.gestureLockView.setPWConfirmlock = ^(){
[hintLlabel showNormalMsg:CoreLockPWDTitleConfirm];
}; /** password长度不够 */
self.gestureLockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){ [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"最少链接%@个点。请又一次输入",@(CoreLockMinItemCount)]];
}; /** 两次password不一致 */
self.gestureLockView.setPWSErrorTwiceDiffBlock = ^(NSString *pwd1,NSString *pwdNow){ [self.hintLlabel showWarnMsg:CoreLockPWDDiffTitle]; //self.navigationItem.rightBarButtonItem = self.resetItem;
}; /** 第一次输入password:正确 */
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];
}; /** 再次输入password一致 */
self.gestureLockView.setPWTwiceSameBlock = ^(NSString *pwd){
NSLog(@"pwd==%@",pwd);
[self.hintLlabel showNormalMsg:CoreLockPWSuccessTitle];
self.navigationItem.rightBarButtonItem=nil;
//存储password
//[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:@"password获取失败了,请您登录系统"];
[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:@"手势password不对,请您又一次登录系统!"];
[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:@"password错了,还有%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:@"password错误。还有%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代表未设置手势password。这样的情况下要绘制2次,1,代表的时设置过手势password,可是要关闭这个手势,这是就要验证手势,见下图:

2代表的是,点击改动的标志,这个逻辑是先验证,然后在又一次绘制新的手势,这个过程有3步,主要验证->绘制第一次->绘制第二次。

"SWProperties.h" 主要是我的本地sqlitedb的操作,用于保存手势password设置未设置的标志,这里不做具体说明,假设你不保存能够不须要

"SWTool.h" 主要是一些工具类,这里主要用到 空字符串的推断。请自己查找

"TextDialog.h"是点击验证登录password时的弹出框。请自己找,效果:

"MBProgressHUD.h"这个不用说了吧,验证的时候肯定要花费时间的。一个等待的提示,不可少

"SWCallWebservice.h"封装的验证登录password的类

"RetCodeMessageBean.h"验证登录返回后的对象

刚開始的时候不可能一下把全部功能都做出来。那些临时用不到的先凝视掉,然后慢慢加入。所以,假设你遇到各种编译只是,各种红叉请不要心急,一步一步来,把最基本的东西做了即可了。

因为我没有把demo中的 CLLockVC相关类copy过来,所以有些修改,首先把:

typedef enum{

    //设置password
CoreLockTypeSetPwd=0, //输入并验证password
CoreLockTypeVeryfiPwd, //改动password
CoreLockTypeModifyPwd, }CoreLockType;

定义的这些东西放到CLLockView.h类中,并在这个类中加入属性:

@property (nonatomic,assign) BOOL needLine;

这个主要相应显示手势轨迹的功能,当然。这个主要用在手势锁屏后才干看到,假设你不须要也能够去掉。

再把这个类中的方法加入一个參数

@property (nonatomic,copy) void (^setPWFirstRightBlock)(NSString *pwd);

在把相应的CLLockView.m文件里找到以下这一句。并改动:

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 中的内容

//
// 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里面推断假设设置了手势。就跳转到手势登录界面。手势登录效果图:

代码也非常easy,在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{
/** password长度不够 */
self.gestureLockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){
tryCnt--;
usernoLabel.hidden=NO;
if(tryCnt<=0){
[self.hintLlabel showWarnMsg:@"password错了,请您登录系统"];
[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:@"password错了。还有%ld次机会",tryCnt]];
}
};
/** 验证 */
self.gestureLockView.verifyPwdBlock = ^(NSString *pwd){
NSLog(@"verifyPwdBlock.pwd==%@",pwd);
NSString *local = [prop getValuebyFieldName:@"gesturePwd"];
if([SWTool isEmptyString:local]){
[self.hintLlabel showWarnMsg:@"password获取失败了,请您登录系统"];
[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:@"password错了,请您登录系统"];
[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:@"password错了。还有%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。我发现滑动的适合。两个点之间我略微的从外面绕一下,就导致中间的点没连上,真是郁闷啊,因为时间比較冲忙,后面我肯定也要解决问题的,只是。会不会写下来,就不知道了,提供一下思路,上一个点与下一个点取中间的坐标,推断这个坐标里面是否有button。有的情况,推断是否已经加入,没有就加进去。

因为是第一次做ios。并且还是在地铁上花了一个星期不到的时间看着电子书学习ios,然后用1个月的时间完毕公司的产品,前面也说过。我是做的android版。然后相应的ios版,也是我来做,时间非常的仓促。非常多的地方也有不懂之处,代码写的也比較乱,希望大家不要歧视。

。。。

嘛,就这样愉快的做ios吧。啦啦啦~~~~~~

[ios仿系列]仿支付宝手势解码的更多相关文章

  1. iOS-高仿支付宝手势解锁(九宫格)

    概述 高仿支付宝手势解锁, 通过手势枚举去实现手势密码相对应操作. 详细 代码下载:http://www.demodashi.com/demo/10706.html 基上篇[TouchID 指纹解锁] ...

  2. (android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇

    从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据 ...

  3. (android高仿系列)今日头条 --新闻阅读器 (二)

    高仿今日头条 --- 第一篇:(android高仿系列)今日头条 --新闻阅读器 (一)    上次,已经完毕了头部新闻分类栏目的拖动效果. 这篇文章是继续去完好APP 今日头条  这个新闻阅读器的其 ...

  4. h5仿微信、支付宝数字键盘|微信支付键盘|支付宝付款键盘

    html5仿微信支付数字键盘|仿支付宝键盘|h5仿微信密码输入键盘|自定义数字键盘 很早之前由于项目需求,就有开发过一个h5仿微信支付键盘,这几天就把之前的数字键盘模块独立出来,重新整理开发成demo ...

  5. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  6. iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...

  7. iOS开发系列--让你的应用“动”起来

    --iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...

  8. iOS开发系列--让你的应用“动”起来

    --iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...

  9. IOS开发系列 --- 核心动画

    原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...

随机推荐

  1. UITableView性能优化及手工绘制UITableViewCell

    提高表视图的性能 UITableView作为应用中最常用的视图,它的性能优化问题几乎是经常提及.下面对在非网络访问情况下的表视图性能优化进行了主要的几点说明: 1.自定义类或XIB文件时 在系统提供的 ...

  2. Android 进行单元測试难在哪-part3

    原文链接 : HOW TO MAKE OUR ANDROID APPS UNIT TESTABLE (PT. 1) 原文作者 : Matthew Dupree 译文出自 : 开发技术前线 www.de ...

  3. C#反射Assembly 具体说明

    1.对C#反射机制的理解 2.概念理解后,必须找到方法去完毕,给出管理的主要语法 3.终于给出有用的样例,反射出来dll中的方法 反射是一个程序集发现及执行的过程,通过反射能够得到*.exe或*.dl ...

  4. [Android阅读代码]android-async-http源码学习一

    android-async-http 下载地址 一个比较常用的Http请求库,基于org.apache.http对http操作进行封装. 特点: 1.每一个HTTP请求发生在UI线程之外,Client ...

  5. Struts工作机制图+OGNL+EL+值栈(Map,对象栈)

    struts 值栈  通过get set方法 方便的获取,设置属性值      比如从jsp页面传来的參数...从Action设置jsp所要回显的内容 注意EL表达式,struts2对request进 ...

  6. 1.VMwareTools安装

     1 选中虚拟机.右击.然后点击:安装Vmware-tool(最好是有网络的情况下安装) 2 将Vmware-tool的安装文件复制到暂时文件夹下,截图例如以下: 3 解压VMwareTools- ...

  7. 获取CentOS软件源中的updates包

    之前在本地网络中建了一个CentOS软件源,挺好用的,可是发现有些软件还是装不上,因为系统安装盘中的包并不全,有些软件的依赖在updates源中,updates源在网上,怎么把其中的包拿到呢?一种方法 ...

  8. 【UVA】10012 - How Big Is It?(暴力)

    使用DFS枚举所有的安排.每次加入后,当一个圆.他的立场是最大的,并已加入了圆环中的所有切线位置前面. 14383635 10012 option=com_onlinejudge&Itemid ...

  9. hdu3622(二分+two-sat)

    传送门:Bomb Game 题意:给n对炸弹可以放置的位置(每个位置为一个二维平面上的点),每次放置炸弹是时只能选择这一对中的其中一个点,每个炸弹爆炸的范围半径都一样,控制爆炸的半径使得所有的爆炸范围 ...

  10. sdbntrjm57k

    http://www.zhihu.com/collection/24337307 http://www.zhihu.com/collection/24337259 http://www.zhihu.c ...