[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;

定义的这些东西放到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里面判断如果设置了手势,就跳转到手势登录界面,手势登录效果图:





代码也很简单,在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仿系列
上一篇【android仿系列进阶篇】android 支付宝手机网页支付
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭