标签:
密码锁功能的实现
一个ios手势密码功能实现
ipad/iphone 都可以用
没有使用图片,里面可以通过view自己添加
keychain做的数据持久化,利用苹果官方KeychainItemWrapper类
keychain存储的数据不会因为删除app而清除记录,请调用-(void)clear
清除储存密码。
下载后直接把 GesturePassword 下的GesturePassword文件丢到项目中去
在 TARGETS - Build Phases - "KeychainItemWrapper.m" - Compiler Flags (-fno-objc-arc)
在需要的地方直接可以调用ViewController
第一次的时候会两次验证密码
以后便会以这个密码进行确认
清空密码可以调用 - (void)clear
- (void)verify
验证手势密码在这里
- (void)reset
重置手势密码在这 (第一次回调用到这里进行第一次设置
保存于读取密码:
直接贴代码 KeychainItemWrapper *keychain=[[KeychainItemWrapper alloc] initWithIdentifier:@"xxxxxx" accessGroup:nil];//xxxx 自定义 保存 [keyWrapper setObject:@"myChainValues" forKey:(id)kSecAttrService]; [keyWrapper setObject:[usernameTextField text] forKey:(id)kSecAttrAccount];// 上面两行用来标识一个Item [keyWrapper setObject:[passwordTextField text] forKey:(id)kSecValueData]; 读取 [usernameTextField setText:[keyWrapper objectForKey:(id)kSecAttrAccount]]; [passwordTextField setText:[keyWrapper objectForKey:(id)kSecValueData]]; 另外需要引入Security.framework 和KeychainItemWrapper头文件(百度一下多得是)
下面简单的实现一下
一:我们先导入这个框架
二:新建一个手势密码的View分别在.h和.m文件中实现以下代码
GesturePasswordView.h
1 @protocol GesturePasswordDelegate <NSObject> 2 3 - (void)forget; 4 - (void)change; 5 6 @end 7 8 #import <UIKit/UIKit.h> 9 #import "TentacleView.h" 10 11 @interface GesturePasswordView : UIView<TouchBeginDelegate> 12 13 @property (nonatomic,strong) TentacleView * tentacleView; 14 15 @property (nonatomic,strong) UILabel * state; 16 17 @property (nonatomic,assign) id<GesturePasswordDelegate> gesturePasswordDelegate; 18 19 @property (nonatomic,strong) UIImageView * imgView; 20 @property (nonatomic,strong) UIButton * forgetButton; 21 @property (nonatomic,strong) UIButton * changeButton; 22 23 @end
GesturePasswordView.m
1 #import "GesturePasswordView.h" 2 #import "GesturePasswordButton.h" 3 #import "TentacleView.h" 4 5 @implementation GesturePasswordView { 6 NSMutableArray * buttonArray; 7 8 CGPoint lineStartPoint; 9 CGPoint lineEndPoint; 10 11 } 12 @synthesize imgView; 13 @synthesize forgetButton; 14 @synthesize changeButton; 15 16 @synthesize tentacleView; 17 @synthesize state; 18 @synthesize gesturePasswordDelegate; 19 20 - (id)initWithFrame:(CGRect)frame 21 { 22 self = [super initWithFrame:frame]; 23 if (self) { 24 // Initialization code 25 buttonArray = [[NSMutableArray alloc]initWithCapacity:0]; 26 27 UIView * view = [[UIView alloc]initWithFrame:CGRectMake(frame.size.width/2-160, frame.size.height/2-80, 320, 320)]; 28 for (int i=0; i<9; i++) { 29 NSInteger row = i/3; 30 NSInteger col = i%3; 31 // Button Frame 32 33 NSInteger distance = 320/3; 34 NSInteger size = distance/1.5; 35 NSInteger margin = size/4; 36 GesturePasswordButton * gesturePasswordButton = [[GesturePasswordButton alloc]initWithFrame:CGRectMake(col*distance+margin, row*distance, size, size)]; 37 [gesturePasswordButton setTag:i]; 38 [view addSubview:gesturePasswordButton]; 39 [buttonArray addObject:gesturePasswordButton]; 40 } 41 frame.origin.y=0; 42 [self addSubview:view]; 43 tentacleView = [[TentacleView alloc]initWithFrame:view.frame]; 44 [tentacleView setButtonArray:buttonArray]; 45 [tentacleView setTouchBeginDelegate:self]; 46 [self addSubview:tentacleView]; 47 48 state = [[UILabel alloc]initWithFrame:CGRectMake(frame.size.width/2-140, frame.size.height/2-120, 280, 30)]; 49 [state setTextAlignment:NSTextAlignmentCenter]; 50 [state setFont:[UIFont systemFontOfSize:14.f]]; 51 [self addSubview:state]; 52 53 54 imgView = [[UIImageView alloc]initWithFrame:CGRectMake(frame.size.width/2-35, frame.size.width/2-80, 70, 70)]; 55 [imgView setBackgroundColor:[UIColor whiteColor]]; 56 [imgView.layer setCornerRadius:35]; 57 [imgView.layer setBorderColor:[UIColor grayColor].CGColor]; 58 [imgView.layer setBorderWidth:3]; 59 [self addSubview:imgView]; 60 61 forgetButton = [[UIButton alloc]initWithFrame:CGRectMake(frame.size.width/2-150, frame.size.height/2+220, 120, 30)]; 62 [forgetButton.titleLabel setFont:[UIFont systemFontOfSize:14]]; 63 [forgetButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 64 [forgetButton setTitle:@"忘记手势密码" forState:UIControlStateNormal]; 65 [forgetButton addTarget:self action:@selector(forget) forControlEvents:UIControlEventTouchDown]; 66 [self addSubview:forgetButton]; 67 68 changeButton = [[UIButton alloc]initWithFrame:CGRectMake(frame.size.width/2+30, frame.size.height/2+220, 120, 30)]; 69 [changeButton.titleLabel setFont:[UIFont systemFontOfSize:14]]; 70 [changeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 71 [changeButton setTitle:@"修改手势密码" forState:UIControlStateNormal]; 72 [changeButton addTarget:self action:@selector(change) forControlEvents:UIControlEventTouchDown]; 73 [self addSubview:changeButton]; 74 } 75 76 return self; 77 } 78 79 // Only override drawRect: if you perform custom drawing. 80 // An empty implementation adversely affects performance during animation. 81 82 - (void)drawRect:(CGRect)rect 83 { 84 // Drawing code 85 CGContextRef context = UIGraphicsGetCurrentContext(); 86 87 CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); 88 CGFloat colors[] = 89 { 90 134 / 255.0, 157 / 255.0, 147 / 255.0, 1.00, 91 3 / 255.0, 3 / 255.0, 37 / 255.0, 1.00, 92 }; 93 CGGradientRef gradient = CGGradientCreateWithColorComponents 94 (rgb, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4)); 95 CGColorSpaceRelease(rgb); 96 CGContextDrawLinearGradient(context, gradient,CGPointMake 97 (0.0,0.0) ,CGPointMake(0.0,self.frame.size.height), 98 kCGGradientDrawsBeforeStartLocation); 99 } 100 101 - (void)gestureTouchBegin { 102 [self.state setText:@""]; 103 } 104 105 -(void)forget{ 106 [gesturePasswordDelegate forget]; 107 } 108 109 -(void)change{ 110 [gesturePasswordDelegate change]; 111 } 112 113 114 @end
三:再自定义一个View用于实现界面的布局与处理
TentacleView.h
1 #import <UIKit/UIKit.h> 2 3 @protocol ResetDelegate <NSObject> 4 5 - (BOOL)resetPassword:(NSString *)result; 6 7 @end 8 9 @protocol VerificationDelegate <NSObject> 10 11 - (BOOL)verification:(NSString *)result; 12 13 @end 14 15 @protocol TouchBeginDelegate <NSObject> 16 17 - (void)gestureTouchBegin; 18 19 @end 20 21 22 23 @interface TentacleView : UIView 24 25 @property (nonatomic,strong) NSArray * buttonArray; 26 27 @property (nonatomic,assign) id<VerificationDelegate> rerificationDelegate; 28 29 @property (nonatomic,assign) id<ResetDelegate> resetDelegate; 30 31 @property (nonatomic,assign) id<TouchBeginDelegate> touchBeginDelegate; 32 33 /* 34 1: Verify 35 2: Reset 36 */ 37 @property (nonatomic,assign) NSInteger style; 38 39 - (void)enterArgin; 40 41 @end
TentacleView.m
1 #import "TentacleView.h" 2 #import "GesturePasswordButton.h" 3 4 @implementation TentacleView { 5 CGPoint lineStartPoint; 6 CGPoint lineEndPoint; 7 8 NSMutableArray * touchesArray; 9 NSMutableArray * touchedArray; 10 BOOL success; 11 } 12 @synthesize buttonArray; 13 @synthesize rerificationDelegate; 14 @synthesize resetDelegate; 15 @synthesize touchBeginDelegate; 16 @synthesize style; 17 18 - (id)initWithFrame:(CGRect)frame 19 { 20 self = [super initWithFrame:frame]; 21 if (self) { 22 // Initialization code 23 touchesArray = [[NSMutableArray alloc]initWithCapacity:0]; 24 touchedArray = [[NSMutableArray alloc]initWithCapacity:0]; 25 [self setBackgroundColor:[UIColor clearColor]]; 26 [self setUserInteractionEnabled:YES]; 27 success = 1; 28 } 29 return self; 30 } 31 32 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 33 CGPoint touchPoint; 34 UITouch *touch = [touches anyObject]; 35 [touchesArray removeAllObjects]; 36 [touchedArray removeAllObjects]; 37 [touchBeginDelegate gestureTouchBegin]; 38 success=1; 39 if (touch) { 40 touchPoint = [touch locationInView:self]; 41 for (int i=0; i<buttonArray.count; i++) { 42 GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]); 43 [buttonTemp setSuccess:YES]; 44 [buttonTemp setSelected:NO]; 45 if (CGRectContainsPoint(buttonTemp.frame,touchPoint)) { 46 CGRect frameTemp = buttonTemp.frame; 47 CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/2,frameTemp.origin.y+frameTemp.size.height/2); 48 NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",point.x],@"x",[NSString stringWithFormat:@"%f",point.y],@"y", nil]; 49 [touchesArray addObject:dict]; 50 lineStartPoint = touchPoint; 51 } 52 [buttonTemp setNeedsDisplay]; 53 } 54 55 [self setNeedsDisplay]; 56 } 57 } 58 59 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 60 CGPoint touchPoint; 61 UITouch *touch = [touches anyObject]; 62 if (touch) { 63 touchPoint = [touch locationInView:self]; 64 for (int i=0; i<buttonArray.count; i++) { 65 GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]); 66 if (CGRectContainsPoint(buttonTemp.frame,touchPoint)) { 67 if ([touchedArray containsObject:[NSString stringWithFormat:@"num%d",i]]) { 68 lineEndPoint = touchPoint; 69 [self setNeedsDisplay]; 70 return; 71 } 72 [touchedArray addObject:[NSString stringWithFormat:@"num%d",i]]; 73 [buttonTemp setSelected:YES]; 74 [buttonTemp setNeedsDisplay]; 75 CGRect frameTemp = buttonTemp.frame; 76 CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/2,frameTemp.origin.y+frameTemp.size.height/2); 77 NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",point.x],@"x",[NSString stringWithFormat:@"%f",point.y],@"y",[NSString stringWithFormat:@"%d",i],@"num", nil]; 78 [touchesArray addObject:dict]; 79 break; 80 } 81 } 82 lineEndPoint = touchPoint; 83 [self setNeedsDisplay]; 84 } 85 } 86 87 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 88 NSMutableString * resultString=[NSMutableString string]; 89 for ( NSDictionary * num in touchesArray ){ 90 if(![num objectForKey:@"num"])break; 91 [resultString appendString:[num objectForKey:@"num"]]; 92 } 93 if(style==1){ 94 success = [rerificationDelegate verification:resultString]; 95 } 96 else { 97 success = [resetDelegate resetPassword:resultString]; 98 } 99 100 for (int i=0; i<touchesArray.count; i++) { 101 NSInteger selection = [[[touchesArray objectAtIndex:i] objectForKey:@"num"]intValue]; 102 GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:selection]); 103 [buttonTemp setSuccess:success]; 104 [buttonTemp setNeedsDisplay]; 105 } 106 [self setNeedsDisplay]; 107 } 108 109 // Only override drawRect: if you perform custom drawing. 110 // An empty implementation adversely affects performance during animation. 111 - (void)drawRect:(CGRect)rect 112 { 113 // Drawing code 114 // if (touchesArray.count<2)return; 115 for (int i=0; i<touchesArray.count; i++) { 116 CGContextRef context = UIGraphicsGetCurrentContext(); 117 if (![[touchesArray objectAtIndex:i] objectForKey:@"num"]) { //防止过快滑动产生垃圾数据 118 [touchesArray removeObjectAtIndex:i]; 119 continue; 120 } 121 if (success) { 122 CGContextSetRGBStrokeColor(context, 2/255.f, 174/255.f, 240/255.f, 0.7);//线条颜色 123 } 124 else { 125 CGContextSetRGBStrokeColor(context, 208/255.f, 36/255.f, 36/255.f, 0.7);//红色 126 } 127 128 CGContextSetLineWidth(context,5); 129 CGContextMoveToPoint(context, [[[touchesArray objectAtIndex:i] objectForKey:@"x"] floatValue], [[[touchesArray objectAtIndex:i] objectForKey:@"y"] floatValue]); 130 if (i<touchesArray.count-1) { 131 CGContextAddLineToPoint(context, [[[touchesArray objectAtIndex:i+1] objectForKey:@"x"] floatValue],[[[touchesArray objectAtIndex:i+1] objectForKey:@"y"] floatValue]); 132 } 133 else{ 134 if (success) { 135 CGContextAddLineToPoint(context, lineEndPoint.x,lineEndPoint.y); 136 } 137 } 138 CGContextStrokePath(context); 139 } 140 } 141 142 - (void)enterArgin { 143 [touchesArray removeAllObjects]; 144 [touchedArray removeAllObjects]; 145 for (int i=0; i<buttonArray.count; i++) { 146 GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]); 147 [buttonTemp setSelected:NO]; 148 [buttonTemp setSuccess:YES]; 149 [buttonTemp setNeedsDisplay]; 150 } 151 152 [self setNeedsDisplay]; 153 }
四:自定义一个密码按钮的View
GesturePasswordButton.h
1 #import <UIKit/UIKit.h> 2 3 @interface GesturePasswordButton : UIView 4 5 @property (nonatomic,assign) BOOL selected; 6 7 @property (nonatomic,assign) BOOL success; 8 9 @end
GesturePasswordButton.m
1 #import "GesturePasswordButton.h" 2 3 #define bounds self.bounds 4 5 @implementation GesturePasswordButton 6 @synthesize selected; 7 @synthesize success; 8 9 - (id)initWithFrame:(CGRect)frame 10 { 11 self = [super initWithFrame:frame]; 12 if (self) { 13 // Initialization code 14 success=YES; 15 [self setBackgroundColor:[UIColor clearColor]]; 16 } 17 return self; 18 } 19 20 21 // Only override drawRect: if you perform custom drawing. 22 // An empty implementation adversely affects performance during animation. 23 - (void)drawRect:(CGRect)rect 24 { 25 // Drawing code 26 CGContextRef context = UIGraphicsGetCurrentContext(); 27 28 if (selected) { 29 if (success) { 30 CGContextSetRGBStrokeColor(context, 2/255.f, 174/255.f, 240/255.f,1);//线条颜色 31 CGContextSetRGBFillColor(context,2/255.f, 174/255.f, 240/255.f,1); 32 } 33 else { 34 CGContextSetRGBStrokeColor(context, 208/255.f, 36/255.f, 36/255.f,1);//线条颜色 35 CGContextSetRGBFillColor(context,208/255.f, 36/255.f, 36/255.f,1); 36 } 37 CGRect frame = CGRectMake(bounds.size.width/2-bounds.size.width/8+1, bounds.size.height/2-bounds.size.height/8, bounds.size.width/4, bounds.size.height/4); 38 39 CGContextAddEllipseInRect(context,frame); 40 CGContextFillPath(context); 41 } 42 else{ 43 CGContextSetRGBStrokeColor(context, 1,1,1,1);//线条颜色 44 } 45 46 CGContextSetLineWidth(context,2); 47 CGRect frame = CGRectMake(2, 2, bounds.size.width-3, bounds.size.height-3); 48 CGContextAddEllipseInRect(context,frame); 49 CGContextStrokePath(context); 50 if (success) { 51 CGContextSetRGBFillColor(context,30/255.f, 175/255.f, 235/255.f,0.3); 52 } 53 else { 54 CGContextSetRGBFillColor(context,208/255.f, 36/255.f, 36/255.f,0.3); 55 } 56 CGContextAddEllipseInRect(context,frame); 57 if (selected) { 58 CGContextFillPath(context); 59 } 60 61 } 62 63 64 @end
五:前面的步骤都准备好了之后,我们就需要在控制器里面实现相应的代码
GesturePasswordController.h
1 #import <UIKit/UIKit.h> 2 #import "TentacleView.h" 3 #import "GesturePasswordView.h" 4 5 @interface GesturePasswordController : UIViewController <VerificationDelegate,ResetDelegate,GesturePasswordDelegate> 6 7 - (void)clear; 8 9 - (BOOL)exist; 10 11 @end
GesturePasswordController.m
1 #import <Security/Security.h> 2 #import <CoreFoundation/CoreFoundation.h> 3 4 #import "GesturePasswordController.h" 5 6 7 #import "KeychainItemWrapper/KeychainItemWrapper.h" 8 9 @interface GesturePasswordController () 10 11 @property (nonatomic,strong) GesturePasswordView * gesturePasswordView; 12 13 @end 14 15 @implementation GesturePasswordController { 16 NSString * previousString; 17 NSString * password; 18 } 19 20 @synthesize gesturePasswordView; 21 22 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 23 { 24 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 25 if (self) { 26 // Custom initialization 27 } 28 return self; 29 } 30 31 - (void)viewDidLoad 32 { 33 [super viewDidLoad]; 34 // Do any additional setup after loading the view. 35 previousString = [NSString string]; 36 KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil]; 37 password = [keychin objectForKey:(__bridge id)kSecValueData]; 38 if ([password isEqualToString:@""]) { 39 40 [self reset]; 41 } 42 else { 43 [self verify]; 44 } 45 } 46 47 - (void)didReceiveMemoryWarning 48 { 49 [super didReceiveMemoryWarning]; 50 // Dispose of any resources that can be recreated. 51 } 52 53 54 #pragma mark - 验证手势密码 55 - (void)verify{ 56 gesturePasswordView = [[GesturePasswordView alloc]initWithFrame:[UIScreen mainScreen].bounds]; 57 [gesturePasswordView.tentacleView setRerificationDelegate:self]; 58 [gesturePasswordView.tentacleView setStyle:1]; 59 [gesturePasswordView setGesturePasswordDelegate:self]; 60 [self.view addSubview:gesturePasswordView]; 61 } 62 63 #pragma mark - 重置手势密码 64 - (void)reset{ 65 gesturePasswordView = [[GesturePasswordView alloc]initWithFrame:[UIScreen mainScreen].bounds]; 66 [gesturePasswordView.tentacleView setResetDelegate:self]; 67 [gesturePasswordView.tentacleView setStyle:2]; 68 // [gesturePasswordView.imgView setHidden:YES]; 69 [gesturePasswordView.forgetButton setHidden:YES]; 70 [gesturePasswordView.changeButton setHidden:YES]; 71 [self.view addSubview:gesturePasswordView]; 72 } 73 74 #pragma mark - 判断是否已存在手势密码 75 - (BOOL)exist{ 76 KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil]; 77 password = [keychin objectForKey:(__bridge id)kSecValueData]; 78 if ([password isEqualToString:@""])return NO; 79 return YES; 80 } 81 82 #pragma mark - 清空记录 83 - (void)clear{ 84 KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil]; 85 [keychin resetKeychainItem]; 86 } 87 88 #pragma mark - 改变手势密码 89 - (void)change{ 90 } 91 92 #pragma mark - 忘记手势密码 93 - (void)forget{ 94 } 95 96 - (BOOL)verification:(NSString *)result{ 97 if ([result isEqualToString:password]) { 98 [gesturePasswordView.state setTextColor:[UIColor colorWithRed:2/255.f green:174/255.f blue:240/255.f alpha:1]]; 99 [gesturePasswordView.state setText:@"输入正确"]; 100 //[self presentViewController:(UIViewController) animated:YES completion:nil]; 101 return YES; 102 } 103 [gesturePasswordView.state setTextColor:[UIColor redColor]]; 104 [gesturePasswordView.state setText:@"手势密码错误"]; 105 return NO; 106 } 107 108 - (BOOL)resetPassword:(NSString *)result{ 109 if ([previousString isEqualToString:@""]) { 110 previousString=result; 111 [gesturePasswordView.tentacleView enterArgin]; 112 [gesturePasswordView.state setTextColor:[UIColor colorWithRed:2/255.f green:174/255.f blue:240/255.f alpha:1]]; 113 [gesturePasswordView.state setText:@"请验证输入密码"]; 114 return YES; 115 } 116 else { 117 if ([result isEqualToString:previousString]) { 118 KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil]; 119 [keychin setObject:@"<帐号>" forKey:(__bridge id)kSecAttrAccount]; 120 [keychin setObject:result forKey:(__bridge id)kSecValueData]; 121 //[self presentViewController:(UIViewController) animated:YES completion:nil]; 122 [gesturePasswordView.state setTextColor:[UIColor colorWithRed:2/255.f green:174/255.f blue:240/255.f alpha:1]]; 123 [gesturePasswordView.state setText:@"已保存手势密码"]; 124 return YES; 125 } 126 else{ 127 previousString =@""; 128 [gesturePasswordView.state setTextColor:[UIColor redColor]]; 129 [gesturePasswordView.state setText:@"两次密码不一致,请重新输入"]; 130 return NO; 131 } 132 } 133 } 134 135 136 137 138 /* 139 #pragma mark - Navigation 140 141 // In a storyboard-based application, you will often want to do a little preparation before navigation 142 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 143 { 144 // Get the new view controller using [segue destinationViewController]. 145 // Pass the selected object to the new view controller. 146 } 147 */
六:最终运行效果如下
标签:
原文地址:http://www.cnblogs.com/iCocos/p/4598581.html