zoukankan      html  css  js  c++  java
  • [ios仿系列]仿支付宝手势解码

    呀~。这么快就转到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吧。啦啦啦~~~~~~



  • 相关阅读:
    使用MaxCompute Java SDK 执行任务卡住了,怎么办?
    通过编辑文件的方式对DNS服务器进行配置
    2009级计算机应用 嵌入式方向课表
    微软首宗针对中国大企业盗版案宣判:获赔217万
    小數點的運算[討論區- PHP新手區] : 台灣PHP聯盟
    Linux C编程一站式学习
    用wget做站点镜像
    2008级嵌入式方向学生 学习成果(创意)
    Linux领航未来操作系统
    fedora12 微软雅黑
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5138328.html
Copyright © 2011-2022 走看看