呀~。这么快就转到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来搞的。假设你有其它方法都行。以下是这个界面的主要代码:

  1. //
  2. // GestureSetupViewController.m
  3. // yktapp
  4. //
  5. // Created by Shuwei on 15/6/29.
  6. // Copyright (c) 2015年 All rights reserved.
  7. //
  8.  
  9. #import "GestureSetupViewController.h"
  10.  
  11. #import "CoreLockConst.h"
  12. #import "CoreArchive.h"
  13. #import "CLLockLabel.h"
  14. #import "CLLockNavVC.h"
  15. #import "CLLockView.h"
  16. #import "CLLockInfoView.h"
  17.  
  18. #import "SWTool.h"
  19. #import "SWProperties.h"
  20. #import "CommonData.h"
  21. #import "TextDialog.h"
  22. #import "MBProgressHUD.h"
  23. #import "SWCallWebservice.h"
  24. #import "RetCodeMessageBean.h"
  25.  
  26. @interface GestureSetupViewController ()
  27. //@property (weak, nonatomic) IBOutlet GestureView *gestureView;
  28. @property (nonatomic,strong) CLLockView * gestureLockView;
  29. @property (nonatomic,strong) CLLockLabel * hintLlabel;
  30. @property (nonatomic,strong) CLLockInfoView * topInforView;
  31. @property (nonatomic,strong) IBOutlet UIBarButtonItem *resetBtn;
  32.  
  33. @end
  34.  
  35. @implementation GestureSetupViewController{
  36. SWProperties *prop;
  37. UIButton *checkLoginBtn;
  38. CoreLockType type;
  39. NSInteger tryCnt;
  40. NSInteger loginCnt;
  41. UITextField *passTxt;
  42. TextDialog *payDialog;
  43. MBProgressHUD *hud;
  44. }
  45. @synthesize hintLlabel;
  46. @synthesize gestureLockView;
  47. @synthesize topInforView;
  48. @synthesize resetBtn;
  49. - (void)viewDidLoad {
  50. [super viewDidLoad];
  51. self.view.backgroundColor=CoreLockViewBgColor;
  52. prop = [SWProperties sharedInstance];
  53. NSString *temp = [prop getValuebyFieldName:@"gestureTryCnt"];
  54. if([SWTool isEmptyString:temp]){
  55. tryCnt = 5;
  56. }else{
  57. tryCnt = temp.integerValue;
  58. }
  59. temp = [prop getValuebyFieldName:@"gestureLoginCnt"];
  60. if([SWTool isEmptyString:temp]){
  61. loginCnt = 3;
  62. }else{
  63. loginCnt = temp.integerValue;
  64. }
  65. hud = [[MBProgressHUD alloc] initWithView:self.view];
  66. [self initView];
  67. resetBtn = [[UIBarButtonItem alloc]init];
  68. resetBtn.title = @"重设";
  69. [resetBtn setTintColor:[UIColor whiteColor]];
  70. }
  71. -(void)initView{
  72. for (UIView * subview in [self.view subviews]) {
  73. [subview removeFromSuperview];
  74. }
  75. CGRect frame= [UIScreen mainScreen].applicationFrame;
  76. CGRect gest = frame;
  77. CGFloat top=0;
  78. if([[CommonData shareInstance].setFlag isEqualToString:@"0"]){
  79. gest = frame;
  80. gest.size.height=44;
  81. gest.size.width=44;
  82. gest.origin.x = self.view.center.x-22;
  83. gest.origin.y +=80;
  84. topInforView = [[CLLockInfoView alloc] initWithFrame:gest];
  85. topInforView.backgroundColor = CoreLockViewBgColor;
  86. [self.view addSubview:topInforView];
  87. top = 130;
  88. type = CoreLockTypeSetPwd;
  89. self.title=@"设置手势password";
  90. }else{
  91. top = 80;
  92. gest = frame;
  93. gest.origin.y = frame.size.height-50;
  94. gest.size.height=44;
  95. gest.size.width=150;
  96. gest.origin.x = self.view.center.x-75;
  97. checkLoginBtn = [[UIButton alloc] initWithFrame:gest];
  98.  
  99. [checkLoginBtn setTitle:@"验证登录password" forState:UIControlStateNormal];
  100. [checkLoginBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  101. [checkLoginBtn setTintColor:[UIColor whiteColor]];
  102. checkLoginBtn.titleLabel.font = [UIFont systemFontOfSize: 16];
  103. [checkLoginBtn addTarget:self action:@selector(checkLogin:) forControlEvents:UIControlEventTouchDown];
  104. [self.view addSubview:checkLoginBtn];
  105. type = CoreLockTypeVeryfiPwd;
  106. self.title=@"验证手势password";
  107. }
  108.  
  109. gest = frame;
  110. gest.size.height=31;
  111. gest.origin.y +=top;
  112. hintLlabel = [[CLLockLabel alloc] initWithFrame:gest];
  113. hintLlabel.textAlignment = NSTextAlignmentCenter;
  114. [self.view addSubview:hintLlabel];
  115. if([[CommonData shareInstance].setFlag isEqualToString:@"0"]){
  116. [self.hintLlabel showNormalMsg:@"绘制解锁图案"];
  117. }else{
  118. [self.hintLlabel showNormalMsg:@"请输入原手势password"];
  119. }
  120. gest = frame;
  121. top +=60;
  122. gest.size.height =frame.size.height/2+20;
  123. gest.origin.y +=top;
  124. gestureLockView = [[CLLockView alloc] initWithFrame:gest];
  125.  
  126. gestureLockView.backgroundColor = CoreLockViewBgColor;
  127. gestureLockView.type = type;
  128. gestureLockView.needLine = YES;
  129. [self.view addSubview:gestureLockView];
  130.  
  131. [self event];
  132. }
  133. - (void)didReceiveMemoryWarning {
  134. [super didReceiveMemoryWarning];
  135. }
  136.  
  137. - (void)resetBtn:(id)sender {
  138. self.navigationItem.rightBarButtonItem=nil;
  139. self.topInforView.success=NO;
  140. self.topInforView.pwd = nil;
  141. [self.topInforView setNeedsDisplay];
  142. [self.hintLlabel showNormalMsg:@"绘制解锁图案"];
  143. [self.gestureLockView resetPwd];
  144. }
  145. -(void)resetView{
  146.  
  147. }
  148.  
  149. -(IBAction)checkLogin:(id)sender{
  150. payDialog = [[TextDialog alloc] initWithTitle:@"请输入登录password" delegate:self cancelButtonTitle:@"取消"
  151. otherButtonTitles:@"确定" ,nil];
  152.  
  153. passTxt = [[UITextField alloc] init];
  154. passTxt.frame = CGRectMake(0, 0, 0, 40);
  155. passTxt.placeholder=@"请输入登录password";
  156. passTxt.delegate = self;
  157. passTxt.borderStyle = UITextBorderStyleRoundedRect;
  158. [passTxt setSecureTextEntry:YES];
  159. passTxt.returnKeyType = UIReturnKeyDone;
  160. [payDialog addCustomerSubview:passTxt];
  161. passTxt.text=@"";
  162. [passTxt becomeFirstResponder];
  163. [payDialog notifayBtnStatus:NO];
  164. [payDialog show];
  165. }
  166.  
  167. -(void)event{
  168.  
  169. /*
  170. * 设置password
  171. */
  172.  
  173. /** 開始输入:确认 */
  174. self.gestureLockView.setPWConfirmlock = ^(){
  175. [hintLlabel showNormalMsg:CoreLockPWDTitleConfirm];
  176. };
  177.  
  178. /** password长度不够 */
  179. self.gestureLockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){
  180.  
  181. [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"最少链接%@个点。请又一次输入",@(CoreLockMinItemCount)]];
  182. };
  183.  
  184. /** 两次password不一致 */
  185. self.gestureLockView.setPWSErrorTwiceDiffBlock = ^(NSString *pwd1,NSString *pwdNow){
  186.  
  187. [self.hintLlabel showWarnMsg:CoreLockPWDDiffTitle];
  188.  
  189. //self.navigationItem.rightBarButtonItem = self.resetItem;
  190. };
  191.  
  192. /** 第一次输入password:正确 */
  193. self.gestureLockView.setPWFirstRightBlock = ^(NSString *pwdM){
  194. NSLog(@"first pwd=%@",pwdM);
  195. self.topInforView.success=YES;
  196. self.topInforView.pwd = pwdM;
  197. [self.topInforView setNeedsDisplay];
  198. self.navigationItem.rightBarButtonItem=resetBtn;
  199. self.navigationItem.rightBarButtonItem.action = @selector(resetBtn:);
  200. self.navigationItem.rightBarButtonItem.target = self;
  201. [self.hintLlabel showNormalMsg:CoreLockPWDTitleConfirm];
  202. };
  203.  
  204. /** 再次输入password一致 */
  205. self.gestureLockView.setPWTwiceSameBlock = ^(NSString *pwd){
  206. NSLog(@"pwd==%@",pwd);
  207. [self.hintLlabel showNormalMsg:CoreLockPWSuccessTitle];
  208. self.navigationItem.rightBarButtonItem=nil;
  209. //存储password
  210. //[CoreArchive setStr:pwd key:CoreLockPWDKey];
  211. if([prop openUserDB]){
  212. [prop writeValueByFieldName:@"gestureFlag" withValue:@"1"];
  213. [prop writeValueByFieldName:@"gesturePwd" withValue:[SWTool toMD5:pwd]];
  214. [prop writeValueByFieldName:@"gestureLine" withValue:@"1"];
  215. [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"];
  216. }
  217. //禁用交互
  218. self.view.userInteractionEnabled = NO;
  219. [self performSelector:@selector(dismis) withObject:nil afterDelay:0.5];
  220. };
  221.  
  222. /** 验证 */
  223. self.gestureLockView.verifyPwdBlock = ^(NSString *pwd){
  224. NSLog(@"verifyPwdBlock.pwd==%@",pwd);
  225. NSString *local = [prop getValuebyFieldName:@"gesturePwd"];
  226. if([SWTool isEmptyString:local]){
  227. [self.hintLlabel showWarnMsg:@"password获取失败了,请您登录系统"];
  228. [self clearDB];
  229. [CommonData shareInstance].needBack = NO;
  230. [prop writeValueByFieldName:@"devicetoken" withValue:nil];
  231. [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.5];
  232. }else{
  233. tryCnt--;
  234. if([[SWTool toMD5:pwd] isEqualToString:local]){
  235. [self doSuccess];
  236. }else{
  237. if(tryCnt<=0){
  238. [self clearDB];
  239. [prop writeValueByFieldName:@"devicetoken" withValue:nil];
  240. [self.hintLlabel showWarnMsg:@"手势password不对,请您又一次登录系统!"];
  241. [CommonData shareInstance].needBack = NO;
  242. [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.5];
  243. }else{
  244. [prop writeValueByFieldName:@"gestureTryCnt" withValue:[NSString stringWithFormat:@"%ld",tryCnt]];
  245. [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"password错了,还有%ld次机会",tryCnt]];
  246. }
  247. }
  248. }
  249. return YES;
  250. };
  251.  
  252. }
  253.  
  254. -(void)doSuccess{
  255. if([[CommonData shareInstance].setFlag isEqualToString:@"1"]){
  256. [self.hintLlabel showNormalMsg:CoreLockVerifySuccesslTitle];
  257. if([prop openUserDB]){
  258. [self clearDB];
  259. }
  260. self.view.userInteractionEnabled = NO;
  261. [self performSelector:@selector(dismis) withObject:nil afterDelay:0.5];
  262. }else if([[CommonData shareInstance].setFlag isEqualToString:@"2"]){
  263. [CommonData shareInstance].setFlag = @"0";
  264. [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"];
  265. [self initView];
  266. }
  267. }
  268. -(void)toLogin{
  269. [self performSegueWithIdentifier:@"toLogin" sender:self];
  270. }
  271. -(void)clearDB{
  272. [prop writeValueByFieldName:@"gestureFlag" withValue:@"0"];
  273. [prop writeValueByFieldName:@"gesturePwd" withValue:nil];
  274. [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"];
  275. [prop writeValueByFieldName:@"gestureLoginCnt" withValue:@"3"];
  276. }
  277. -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  278. {
  279. if(alertView.tag==12){
  280. if(buttonIndex==0){
  281. [self clearDB];
  282. [self performSegueWithIdentifier:@"toLogin" sender:self];
  283. }
  284. }else if(buttonIndex==9000){
  285. [self doCheckLogin];
  286. }else if(alertView.tag==11){
  287. [self checkLogin:nil];
  288. }
  289. }
  290. -(void)willPresentPayAlertView:(UIView *)alertView{
  291. [passTxt becomeFirstResponder];
  292. }
  293.  
  294. - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
  295. {
  296. if(textField==passTxt){
  297.  
  298. if ([string length]>0){
  299. [payDialog notifayBtnStatus:YES];
  300. }else{
  301. [payDialog notifayBtnStatus:NO];
  302. }
  303. }
  304. return YES;
  305. }
  306. - (void)textFieldDidChange:(UITextField *)textField
  307. {
  308. if(textField==passTxt){
  309. if(textField.text.length>0){
  310. [payDialog notifayBtnStatus:YES];
  311. }else {
  312. [payDialog notifayBtnStatus:NO];
  313. }
  314. }
  315. }
  316. -(BOOL)textFieldShouldReturn:(UITextField *)textField{
  317. if(textField.text.length==0){
  318. [passTxt resignFirstResponder];
  319. }else{
  320. [payDialog removeFromSuperview];
  321. [self doCheckLogin];
  322. }
  323. return YES;
  324. }
  325. -(void)doCheckLogin{
  326. [passTxt resignFirstResponder];
  327. [SWTool showHUD:@"正在验证" andView:self.view andHUD:hud];
  328. NSString *userid = [prop getValuebyFieldName:@"sno"];
  329. [SWCallWebservice doCheckLoginWithUserid:userid andPwd:passTxt.text andSuccess:^(NSArray *_ret) {
  330. [hud hide:YES];
  331. if(_ret&&[_ret count]>0){
  332. loginCnt--;
  333. RetCodeMessageBean *bean = [_ret objectAtIndex:0];
  334. if([bean.retcode isEqualToString:@"0"]){
  335. [self doSuccess];
  336. }else{
  337. if(loginCnt<=0){
  338. [SWTool showMessageWithOkButton:@"验证失败了,请又一次登录系统" andDelegate:self];
  339. }else{
  340. [prop writeValueByFieldName:@"gestureLoginCnt" withValue:[NSString stringWithFormat:@"^%ld",loginCnt]];
  341. [SWTool showMessageWithCancelAndOkButton:[NSString stringWithFormat:@"password错误。还有%ld次机会",loginCnt] andTag:11 andDelegate:self andCancelMsg:@"取消" andOkMsg:@"再试一次"];
  342. }
  343. }
  344. }else{
  345. [SWTool showMessageWithOkButton:@"请求失败了。请稍后再试"];
  346. }
  347. } andErrBack:^(NSInteger code) {
  348. [hud hide:YES];
  349. if(code==0){
  350. [SWTool showMessageWithOkButton:@"请求超时了。请稍后再试"];
  351. }else if(code==401){
  352. [CommonData shareInstance].needBack = YES;
  353. [SWTool showMessage:@"用户认证已过期,请又一次登录" seconds:1];
  354. [self performSegueWithIdentifier:@"toLogin" sender:self];
  355. }else{
  356. [SWTool showMessageWithOkButton:@"请求失败了,请稍后再试"];
  357. }
  358. }];
  359. }
  360. -(void)dismis{
  361. [self performSegueWithIdentifier:@"exitToMng" sender:self];
  362. }
  363. @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过来,所以有些修改,首先把:

  1. typedef enum{
  2.  
  3. //设置password
  4. CoreLockTypeSetPwd=0,
  5.  
  6. //输入并验证password
  7. CoreLockTypeVeryfiPwd,
  8.  
  9. //改动password
  10. CoreLockTypeModifyPwd,
  11.  
  12. }CoreLockType;

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

  1. @property (nonatomic,assign) BOOL needLine;

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

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

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

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

  1. if(_setPWFirstRightBlock != nil) _setPWFirstRightBlock(self.pwdM);

并改动当中的方法:

  1. -(void)itemHandel:(CLLockItemView *)itemView{
  2.  
  3. //选中
  4. if(self.needLine){
  5. itemView.selected = YES;
  6. }else{
  7. itemView.selected = NO;
  8. }
  9. itemView.need = self.needLine;
  10. //绘制
  11. [self setNeedsDisplay];
  12. }

主要是加了是否须要轨迹的推断

改动 CLLockInfoView.h

  1. @property (nonatomic,assign) BOOL success;
  2. @property (nonatomic,copy) NSString *pwd;

这个主要是用于绘制的时候。头部的小图标里面的小圆圈也相应改变而已。

CLLockInfoView.m 中的内容

  1. //
  2. // CLLockInfoView.m
  3. // CoreLock
  4. //
  5. // Created by 成林 on 15/4/27.
  6. // Copyright (c) 2015年 冯成林. All rights reserved.
  7. //
  8.  
  9. #import "CLLockInfoView.h"
  10. #import "CoreLockConst.h"
  11.  
  12. @implementation CLLockInfoView
  13.  
  14. @synthesize success;
  15. @synthesize pwd;
  16. -(void)drawRect:(CGRect)rect{
  17.  
  18. //获取上下文
  19. CGContextRef ctx = UIGraphicsGetCurrentContext();
  20.  
  21. //设置属性
  22. CGContextSetLineWidth(ctx, CoreLockArcLineW);
  23.  
  24. //设置线条颜色
  25. [CoreLockCircleLineNormalColor set];
  26.  
  27. //新建路径
  28. CGMutablePathRef pathM =CGPathCreateMutable();
  29.  
  30. CGFloat marginV = 3.f;
  31. CGFloat padding = 1.0f;
  32. CGFloat rectWH = (rect.size.width - marginV * 2 - padding*2) / 3;
  33.  
  34. //加入圆形路径
  35. for (NSUInteger i=0; i<9; i++) {
  36.  
  37. NSUInteger row = i % 3;
  38. NSUInteger col = i / 3;
  39.  
  40. CGFloat rectX = (rectWH + marginV) * row + padding;
  41.  
  42. CGFloat rectY = (rectWH + marginV) * col + padding;
  43.  
  44. CGRect rect = CGRectMake(rectX, rectY, rectWH, rectWH);
  45. if(success&&pwd){
  46. if ([pwd rangeOfString:[NSString stringWithFormat:@"%ld",i]].location != NSNotFound) {
  47. CGContextSetRGBFillColor(ctx,34/255.f, 178/255.f, 246/255.f,1);
  48. CGContextAddEllipseInRect(ctx,rect);
  49. //CGPathAddEllipseInRect(pathM, NULL, rect);
  50. CGContextFillPath(ctx);
  51. }else{
  52. CGPathAddEllipseInRect(pathM, NULL, rect);
  53. }
  54.  
  55. }else{
  56. CGPathAddEllipseInRect(pathM, NULL, rect);
  57. }
  58. }
  59.  
  60. //加入路径
  61. CGContextAddPath(ctx, pathM);
  62.  
  63. //绘制路径
  64. CGContextStrokePath(ctx);
  65.  
  66. //释放路径
  67. CGPathRelease(pathM);
  68. }
  69.  
  70. @end

到此,对于demo的改动已基本结束。不得不说,这位大神的demo很强大

以下是关于怎样启动或跳转到手势解锁界面的

说明一下,我的启动画面是自己做的。并没实用系统提供的launchScreen

所以,登录跳转还是比較方便,在启动画面的controller里面推断假设设置了手势。就跳转到手势登录界面。手势登录效果图:

代码也非常easy,在storyboard中拉一个viewcontroller。选择好我们的手势登录类即可了:

  1. //
  2. // GestureLoginViewController.m
  3. //
  4. //
  5. // Created by job on 15/6/29.
  6. // Copyright (c) 2015年. All rights reserved.
  7. //
  8.  
  9. #import "GestureLoginViewController.h"
  10. #import "SWTool.h"
  11. #import "CoreLockConst.h"
  12. #import "CoreArchive.h"
  13. #import "CLLockLabel.h"
  14. #import "CLLockNavVC.h"
  15. #import "CLLockView.h"
  16. #import "CLLockInfoView.h"
  17. #import "SWProperties.h"
  18. #import "CommonData.h"
  19.  
  20. @interface GestureLoginViewController ()
  21. @property (nonatomic,strong) CLLockView * gestureLockView;
  22. @property (nonatomic,strong) CLLockLabel * hintLlabel;
  23. @end
  24.  
  25. @implementation GestureLoginViewController{
  26. SWProperties *prop;
  27. UIButton *checkLoginBtn;
  28. CoreLockType type;
  29. NSInteger tryCnt;
  30. NSInteger loginCnt;
  31. UIImageView *logo;
  32. UILabel *usernoLabel;
  33. NSString *gestureLine;
  34. }
  35. @synthesize gestureLockView;
  36. @synthesize hintLlabel;
  37.  
  38. - (void)viewDidLoad {
  39. [super viewDidLoad];
  40. type = CoreLockTypeVeryfiPwd;
  41. self.view.backgroundColor=CoreLockViewBgColor;
  42. prop = [SWProperties sharedInstance];
  43. gestureLine = [prop getValuebyFieldName:@"gestureLine"];
  44. NSString *temp = [prop getValuebyFieldName:@"gestureTryCnt"];
  45. if([SWTool isEmptyString:temp]){
  46. tryCnt = 5;
  47. }else{
  48. tryCnt = temp.integerValue;
  49. }
  50.  
  51. [self initView];
  52. }
  53.  
  54. - (void)didReceiveMemoryWarning {
  55. [super didReceiveMemoryWarning];
  56. }
  57.  
  58. -(void)initView{
  59. for (UIView * subview in [self.view subviews]) {
  60. [subview removeFromSuperview];
  61. }
  62. CGRect frame= [UIScreen mainScreen].applicationFrame;
  63. CGRect gest = frame;
  64. CGFloat top=60;
  65.  
  66. logo = [[UIImageView alloc] initWithFrame:CGRectMake((frame.size.width-70)/2, top, 70, 70)];
  67. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
  68. NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_header.jpg",prop.gid]];
  69. UIImage *theImage = [UIImage imageWithContentsOfFile:filePath];
  70. if(!theImage){
  71. theImage =[UIImage imageNamed:@"ic_head.png"];
  72. }
  73. logo.image = theImage;
  74. [logo.layer setCornerRadius:(35)];
  75. [logo.layer setMasksToBounds:YES];
  76. [self.view addSubview:logo];
  77. top = 135;
  78.  
  79. usernoLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, top, frame.size.width, 12)];
  80. usernoLabel.textAlignment=NSTextAlignmentCenter;
  81. usernoLabel.font = [UIFont systemFontOfSize: 10];
  82. usernoLabel.hidden=YES;
  83. usernoLabel.textColor = [UIColor whiteColor];
  84. NSString *temp = [prop getValuebyFieldName:@"sno"];
  85. usernoLabel.text = temp;
  86. [self.view addSubview:usernoLabel];
  87.  
  88. top = 130;
  89. gest = frame;
  90. gest.size.height=22;
  91. gest.origin.y +=top;
  92. hintLlabel = [[CLLockLabel alloc] initWithFrame:gest];
  93. hintLlabel.textAlignment = NSTextAlignmentCenter;
  94. [self.view addSubview:hintLlabel];
  95.  
  96. gest = frame;
  97. top +=22;
  98. gest.size.height =gest.size.height/2+10;
  99. gest.origin.y +=top;
  100. gestureLockView = [[CLLockView alloc] initWithFrame:gest];
  101.  
  102. gestureLockView.backgroundColor = CoreLockViewBgColor;
  103. gestureLockView.type = type;
  104. if(![SWTool isEmptyString:gestureLine]&&[gestureLine isEqualToString:@"0"]){
  105. gestureLockView.needLine = NO;
  106. }else{
  107. gestureLockView.needLine = YES;
  108. }
  109.  
  110. [self.view addSubview:gestureLockView];
  111. gest = frame;
  112. gest.origin.y = gestureLockView.frame.origin.y+gestureLockView.frame.size.height+20;
  113. gest.size.height=44;
  114. gest.size.width=100;
  115. gest.origin.x = frame.size.width-135;;
  116. checkLoginBtn = [[UIButton alloc] initWithFrame:gest];
  117.  
  118. [checkLoginBtn setTitle:@"其它方式登录" forState:UIControlStateNormal];
  119. [checkLoginBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  120. [checkLoginBtn setTintColor:[UIColor whiteColor]];
  121. [checkLoginBtn addTarget:self action:@selector(otherLogin:) forControlEvents:UIControlEventTouchDown];
  122. checkLoginBtn.titleLabel.font = [UIFont systemFontOfSize: 15];
  123. [self.view addSubview:checkLoginBtn];
  124. [self event];
  125. }
  126. -(void)event{
  127. /** password长度不够 */
  128. self.gestureLockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){
  129. tryCnt--;
  130. usernoLabel.hidden=NO;
  131. if(tryCnt<=0){
  132. [self.hintLlabel showWarnMsg:@"password错了,请您登录系统"];
  133. [self clearDB];
  134. [CommonData shareInstance].needBack = NO;
  135. [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.2];
  136. }else{
  137. [prop writeValueByFieldName:@"gestureTryCnt" withValue:[NSString stringWithFormat:@"%ld",tryCnt]];
  138. [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"password错了。还有%ld次机会",tryCnt]];
  139. }
  140. };
  141. /** 验证 */
  142. self.gestureLockView.verifyPwdBlock = ^(NSString *pwd){
  143. NSLog(@"verifyPwdBlock.pwd==%@",pwd);
  144. NSString *local = [prop getValuebyFieldName:@"gesturePwd"];
  145. if([SWTool isEmptyString:local]){
  146. [self.hintLlabel showWarnMsg:@"password获取失败了,请您登录系统"];
  147. [self clearDB];
  148. [CommonData shareInstance].needBack = NO;
  149. [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.5];
  150. }else{
  151. tryCnt--;
  152. if([[SWTool toMD5:pwd] isEqualToString:local]){
  153. //todo login
  154. [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"0"];
  155. if([CommonData shareInstance].needFinish){
  156. [self dismissViewControllerAnimated:YES completion:nil];
  157. }else{
  158. [self performSegueWithIdentifier:@"toMain" sender:self];
  159. }
  160. [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"];
  161. }else{
  162. usernoLabel.hidden=NO;
  163. if(tryCnt<=0){
  164. [self.hintLlabel showWarnMsg:@"password错了,请您登录系统"];
  165. [self clearDB];
  166. [CommonData shareInstance].needBack = NO;
  167. [self performSelector:@selector(toLogin) withObject:nil afterDelay:0.2];
  168. }else{
  169. [prop writeValueByFieldName:@"gestureTryCnt" withValue:[NSString stringWithFormat:@"%ld",tryCnt]];
  170. [self.hintLlabel showWarnMsg:[NSString stringWithFormat:@"password错了。还有%ld次机会",tryCnt]];
  171. }
  172. }
  173. }
  174. return YES;
  175. };
  176.  
  177. }
  178. -(void)toLogin{
  179. [self performSegueWithIdentifier:@"toLogin" sender:self];
  180. }
  181. -(void)clearDB{
  182. [prop writeValueByFieldName:@"gestureFlag" withValue:@"0"];
  183. [prop writeValueByFieldName:@"gesturePwd" withValue:nil];
  184. [prop writeValueByFieldName:@"gestureTryCnt" withValue:@"5"];
  185. [prop writeValueByFieldName:@"devicetoken" withValue:nil];
  186. [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"0"];
  187. }
  188.  
  189. -(IBAction)otherLogin:(id)sender{
  190. [prop writeValueByFieldName:@"devicetoken" withValue:nil];
  191. [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"0"];
  192. [CommonData shareInstance].needBack = NO;
  193. [self performSegueWithIdentifier:@"toLogin" sender:self];
  194. }
  195. @end

代码相对较少,相信大家经过设置手势功能后,这里也肯定没问题。

最后是其它跳转了,

如今的主要逻辑是。app缓存到后台之后5分钟,我就会跳转到手势锁屏,其它情况,临时没考虑。

所以我在AppDelegate.m中的applicationDidEnterBackground和applicationWillEnterForeground中做了简单的事情。代码例如以下:

  1. - (void)applicationDidEnterBackground:(UIApplication *)application {
  2. NSLog(@"mark3");
  3. NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
  4. NSString *isShowed = [prop getValuebyFieldName:@"pub.gestureShowed"];
  5. if([SWTool isEmptyString:isShowed]||[isShowed isEqualToString:@"0"]){
  6. timer=[date timeIntervalSince1970];
  7. }
  8. }
  9.  
  10. - (void)applicationWillEnterForeground:(UIApplication *)application {
  11. NSString *gesturePwd = [prop getValuebyFieldName:@"gesturePwd"];
  12. NSString *gestureFlag = [prop getValuebyFieldName:@"gestureFlag"];
  13. NSString *token = [prop getValuebyFieldName:@"devicetoken"];
  14.  
  15. if(![SWTool isEmptyString:token]&&![SWTool isEmptyString:gesturePwd]&&![SWTool isEmptyString:gestureFlag]&&[gestureFlag isEqualToString:@"1"]){
  16. NSString *isShowed = [prop getValuebyFieldName:@"pub.gestureShowed"];
  17. if([SWTool isEmptyString:isShowed]||[isShowed isEqualToString:@"0"]){
  18. NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
  19. if(!timer){
  20. timer=[dat timeIntervalSince1970];
  21. }
  22. NSTimeInterval temp = [dat timeIntervalSince1970];
  23. if((temp-timer)>300){
  24. UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
  25. GestureLoginViewController *gestureLoginViewController = (GestureLoginViewController*)[storyboard instantiateViewControllerWithIdentifier:@"gestureLogin"];
  26. [CommonData shareInstance].needFinish = YES;
  27. [prop writeValueByFieldName:@"pub.gestureShowed" withValue:@"1"];
  28.  
  29. UIViewController *topRootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
  30. while (topRootViewController.presentedViewController)
  31. {
  32. topRootViewController = topRootViewController.presentedViewController;
  33. }
  34. [topRootViewController presentViewController:gestureLoginViewController animated:YES completion:nil];
  35. }
  36. }
  37.  
  38. }
  39. }

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. 怎样用Java编写一段代码引发内存泄露

    通过下面步骤能够非常easy产生内存泄露(程序代码不能訪问到某些对象,可是它们仍然保存在内存中): 应用程序创建一个长时间执行的线程(或者使用线程池,会更快地发生内存泄露). 线程通过某个类载入器(能 ...

  2. Ubuntu下实现双屏独立切换

    在编码时,总觉得屏幕大小不够,要是能多个屏多好,可以这样 把你的显示器连接到你的电脑,然后开启一个终端 输入:xrandr 显示如下: LVDS1 connected 1366x768+1024+0 ...

  3. 【iOS开发-71】解决方式:Attempting to badge the application icon but haven&#39;t received permission from the...

    (1)原因 一切都是iOS8捣的鬼.您假设把模拟器换成iOS7.1或者更早的,就不会有这个问题.而如今在iOS8中要实现badge.alert和sound等都需要用户允许才干,由于这些都算做Notif ...

  4. linux LVS DR模式配置

    拓扑图: 测试环境:CentOS 6.5 X86 64位 配置步骤: 1.  安装测试环境 [root@UCS-1 ~]# yum -y install httpd [root@UCS-1 ~]# c ...

  5. poj2411(状压dp)

    题目链接:http://poj.org/problem?id=2411 题意:由1*2 的矩形通过组合拼成大矩形,求拼成指定的大矩形有几种拼法. 分析:如果是横着的就定义11,如果竖着的定义为竖着的0 ...

  6. linux的tr命令

    tr(translate缩写)主要用于删除文件中的控制字符,或进行字符转换. 语法 tr [ -c | -cds | -cs | -C | -Cds | -Cs | -ds | -s] [ -A] S ...

  7. 使用COM提供SafeArray数据

    在前一篇博文<读取SafeArray数据>我们介绍了C#读取安全数组.那么我们的COM怎么编写呢? 1. 定义SAFEARRAY变量 SAFEARRAY *pSArray = NULL; ...

  8. Berkeley DB 使用

    http://www.ibm.com/developerworks/cn/linux/l-embdb/index.html UNIX/LINUX平台下的数据库种类非常多,参考资料1中 列举了其中的大部 ...

  9. 使用Nexus搭建企业maven仓库(二)

    先阅读<使用Nexus搭建企业maven仓库(一)> http://blog.csdn.net/ouyida3/article/details/40747545 1.官网眼下最新的版本号是 ...

  10. cocos2d-x快乐的做让人快乐的游戏3:cocos-2d 3.x中的物理世界

    Cocos2d-x 3.0+ 中全新的封装的物理引擎给了开发人员最大的便捷,你不用再繁琐与各种物理引擎的细节,全然的封装让开发人员能够更快更好的将物理引擎的机制加入�到自己的游戏中,简化的设计是从2. ...