iOS开发——高级技术&密码锁功能的实现

密码锁功能的实现

一个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 重置手势密码在这 (第一次回调用到这里进行第一次设置

iOS开发——高级技术&密码锁功能的实现

保存于读取密码:

直接贴代码

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头文件(百度一下多得是)

下面简单的实现一下

一:我们先导入这个框架

iOS开发——高级技术&密码锁功能的实现

二:新建一个手势密码的View分别在.h和.m文件中实现以下代码

GesturePasswordView.h

 @protocol GesturePasswordDelegate <NSObject>

 - (void)forget;
 - (void)change;

 @end

 #import <UIKit/UIKit.h>
 #import "TentacleView.h"

 @interface GesturePasswordView : UIView<TouchBeginDelegate>

 @property (nonatomic,strong) TentacleView * tentacleView;

 @property (nonatomic,strong) UILabel * state;

 @property (nonatomic,assign) id<GesturePasswordDelegate> gesturePasswordDelegate;

 @property (nonatomic,strong) UIImageView * imgView;
 @property (nonatomic,strong) UIButton * forgetButton;
 @property (nonatomic,strong) UIButton * changeButton;

 @end

GesturePasswordView.m

 #import "GesturePasswordView.h"
 #import "GesturePasswordButton.h"
 #import "TentacleView.h"

 @implementation GesturePasswordView {
     NSMutableArray * buttonArray;

     CGPoint lineStartPoint;
     CGPoint lineEndPoint;

 }
 @synthesize imgView;
 @synthesize forgetButton;
 @synthesize changeButton;

 @synthesize tentacleView;
 @synthesize state;
 @synthesize gesturePasswordDelegate;

 - (id)initWithFrame:(CGRect)frame
 {
     self = [super initWithFrame:frame];
     if (self) {
         // Initialization code
         buttonArray = [[NSMutableArray alloc]initWithCapacity:];

         UIView * view = [[UIView alloc]initWithFrame:CGRectMake(frame.size.width/-, frame.size.height/-, , )];
         ; i<; i++) {
             NSInteger row = i/;
             NSInteger col = i%;
             // Button Frame

             NSInteger distance = /;
             NSInteger size = distance/1.5;
             NSInteger margin = size/;
             GesturePasswordButton * gesturePasswordButton = [[GesturePasswordButton alloc]initWithFrame:CGRectMake(col*distance+margin, row*distance, size, size)];
             [gesturePasswordButton setTag:i];
             [view addSubview:gesturePasswordButton];
             [buttonArray addObject:gesturePasswordButton];
         }
         frame.origin.y=;
         [self addSubview:view];
         tentacleView = [[TentacleView alloc]initWithFrame:view.frame];
         [tentacleView setButtonArray:buttonArray];
         [tentacleView setTouchBeginDelegate:self];
         [self addSubview:tentacleView];

         state = [[UILabel alloc]initWithFrame:CGRectMake(frame.size.width/-, frame.size.height/-, , )];
         [state setTextAlignment:NSTextAlignmentCenter];
         [state setFont:[UIFont systemFontOfSize:.f]];
         [self addSubview:state];

         imgView = [[UIImageView alloc]initWithFrame:CGRectMake(frame.size.width/-, frame.size.width/-, , )];
         [imgView setBackgroundColor:[UIColor whiteColor]];
         [imgView.layer setCornerRadius:];
         [imgView.layer setBorderColor:[UIColor grayColor].CGColor];
         [imgView.layer setBorderWidth:];
         [self addSubview:imgView];

         forgetButton = [[UIButton alloc]initWithFrame:CGRectMake(frame.size.width/-, frame.size.height/+, , )];
         [forgetButton.titleLabel setFont:[UIFont systemFontOfSize:]];
         [forgetButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
         [forgetButton setTitle:@"忘记手势密码" forState:UIControlStateNormal];
         [forgetButton addTarget:self action:@selector(forget) forControlEvents:UIControlEventTouchDown];
         [self addSubview:forgetButton];

         changeButton = [[UIButton alloc]initWithFrame:CGRectMake(frame.size.width/+, frame.size.height/+, , )];
         [changeButton.titleLabel setFont:[UIFont systemFontOfSize:]];
         [changeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
         [changeButton setTitle:@"修改手势密码" forState:UIControlStateNormal];
         [changeButton addTarget:self action:@selector(change) forControlEvents:UIControlEventTouchDown];
         [self addSubview:changeButton];
     }

     return self;
 }

 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

 - (void)drawRect:(CGRect)rect
 {
     // Drawing code
     CGContextRef context = UIGraphicsGetCurrentContext();

     CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
     CGFloat colors[] =
     {
          /  /  / 255.0, 1.00,
          /  /  / 255.0, 1.00,
     };
     CGGradientRef gradient = CGGradientCreateWithColorComponents
     (rgb, colors, NULL, ])*));
     CGColorSpaceRelease(rgb);
     CGContextDrawLinearGradient(context, gradient,CGPointMake
                                 (0.0,0.0) ,CGPointMake(0.0,self.frame.size.height),
                                 kCGGradientDrawsBeforeStartLocation);
 }

 - (void)gestureTouchBegin {
     [self.state setText:@""];
 }

 -(void)forget{
     [gesturePasswordDelegate forget];
 }

 -(void)change{
     [gesturePasswordDelegate change];
 }

 @end

三:再自定义一个View用于实现界面的布局与处理

TentacleView.h
 #import <UIKit/UIKit.h>

 @protocol ResetDelegate <NSObject>

 - (BOOL)resetPassword:(NSString *)result;

 @end

 @protocol VerificationDelegate <NSObject>

 - (BOOL)verification:(NSString *)result;

 @end

 @protocol TouchBeginDelegate <NSObject>

 - (void)gestureTouchBegin;

 @end

 @interface TentacleView : UIView

 @property (nonatomic,strong) NSArray * buttonArray;

 @property (nonatomic,assign) id<VerificationDelegate> rerificationDelegate;

 @property (nonatomic,assign) id<ResetDelegate> resetDelegate;

 @property (nonatomic,assign) id<TouchBeginDelegate> touchBeginDelegate;

 /*
  1: Verify
  2: Reset
  */
 @property (nonatomic,assign) NSInteger style;

 - (void)enterArgin;

 @end
TentacleView.m
 #import "TentacleView.h"
 #import "GesturePasswordButton.h"

 @implementation TentacleView {
     CGPoint lineStartPoint;
     CGPoint lineEndPoint;

     NSMutableArray * touchesArray;
     NSMutableArray * touchedArray;
     BOOL success;
 }
 @synthesize buttonArray;
 @synthesize rerificationDelegate;
 @synthesize resetDelegate;
 @synthesize touchBeginDelegate;
 @synthesize style;

 - (id)initWithFrame:(CGRect)frame
 {
     self = [super initWithFrame:frame];
     if (self) {
         // Initialization code
         touchesArray = [[NSMutableArray alloc]initWithCapacity:];
         touchedArray = [[NSMutableArray alloc]initWithCapacity:];
         [self setBackgroundColor:[UIColor clearColor]];
         [self setUserInteractionEnabled:YES];
         success = ;
     }
     return self;
 }

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     CGPoint touchPoint;
     UITouch *touch = [touches anyObject];
     [touchesArray removeAllObjects];
     [touchedArray removeAllObjects];
     [touchBeginDelegate gestureTouchBegin];
     success=;
     if (touch) {
         touchPoint = [touch locationInView:self];
         ; i<buttonArray.count; i++) {
             GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]);
             [buttonTemp setSuccess:YES];
             [buttonTemp setSelected:NO];
             if (CGRectContainsPoint(buttonTemp.frame,touchPoint)) {
                 CGRect frameTemp = buttonTemp.frame;
                 CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/,frameTemp.origin.y+frameTemp.size.height/);
                 NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",point.x],@"x",[NSString stringWithFormat:@"%f",point.y],@"y", nil];
                 [touchesArray addObject:dict];
                 lineStartPoint = touchPoint;
             }
             [buttonTemp setNeedsDisplay];
         }

         [self setNeedsDisplay];
     }
 }

 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
     CGPoint touchPoint;
     UITouch *touch = [touches anyObject];
     if (touch) {
         touchPoint = [touch locationInView:self];
         ; i<buttonArray.count; i++) {
             GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]);
             if (CGRectContainsPoint(buttonTemp.frame,touchPoint)) {
                 if ([touchedArray containsObject:[NSString stringWithFormat:@"num%d",i]]) {
                     lineEndPoint = touchPoint;
                     [self setNeedsDisplay];
                     return;
                 }
                 [touchedArray addObject:[NSString stringWithFormat:@"num%d",i]];
                 [buttonTemp setSelected:YES];
                 [buttonTemp setNeedsDisplay];
                 CGRect frameTemp = buttonTemp.frame;
                 CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/,frameTemp.origin.y+frameTemp.size.height/);
                 NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",point.x],@"x",[NSString stringWithFormat:@"%f",point.y],@"y",[NSString stringWithFormat:@"%d",i],@"num", nil];
                 [touchesArray addObject:dict];
                 break;
             }
         }
         lineEndPoint = touchPoint;
         [self setNeedsDisplay];
     }
 }

 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
     NSMutableString * resultString=[NSMutableString string];
     for ( NSDictionary * num in touchesArray ){
         if(![num objectForKey:@"num"])break;
         [resultString appendString:[num objectForKey:@"num"]];
     }
     ){
         success = [rerificationDelegate verification:resultString];
     }
     else {
         success = [resetDelegate resetPassword:resultString];
     }

     ; i<touchesArray.count; i++) {
         NSInteger selection = [[[touchesArray objectAtIndex:i] objectForKey:@"num"]intValue];
         GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:selection]);
         [buttonTemp setSuccess:success];
         [buttonTemp setNeedsDisplay];
     }
     [self setNeedsDisplay];
 }

 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
     // Drawing code
 //    if (touchesArray.count<2)return;
     ; i<touchesArray.count; i++) {
         CGContextRef context = UIGraphicsGetCurrentContext();
         if (![[touchesArray objectAtIndex:i] objectForKey:@"num"]) { //防止过快滑动产生垃圾数据
             [touchesArray removeObjectAtIndex:i];
             continue;
         }
         if (success) {
             CGContextSetRGBStrokeColor(context, /.f, /.f, /.f, 0.7);//线条颜色
         }
         else {
             CGContextSetRGBStrokeColor(context, /.f, /.f, /.f, 0.7);//红色
         }

         CGContextSetLineWidth(context,);
         CGContextMoveToPoint(context, [[[touchesArray objectAtIndex:i] objectForKey:@"x"] floatValue], [[[touchesArray objectAtIndex:i] objectForKey:@"y"] floatValue]);
         ) {
             CGContextAddLineToPoint(context, [[[touchesArray objectAtIndex:i+] objectForKey:] objectForKey:@"y"] floatValue]);
         }
         else{
             if (success) {
                 CGContextAddLineToPoint(context, lineEndPoint.x,lineEndPoint.y);
             }
         }
         CGContextStrokePath(context);
     }
 }

 - (void)enterArgin {
     [touchesArray removeAllObjects];
     [touchedArray removeAllObjects];
     ; i<buttonArray.count; i++) {
         GesturePasswordButton * buttonTemp = ((GesturePasswordButton *)[buttonArray objectAtIndex:i]);
         [buttonTemp setSelected:NO];
         [buttonTemp setSuccess:YES];
         [buttonTemp setNeedsDisplay];
     }

     [self setNeedsDisplay];
 }

四:自定义一个密码按钮的View

GesturePasswordButton.h  
 #import <UIKit/UIKit.h>

 @interface GesturePasswordButton : UIView

 @property (nonatomic,assign) BOOL selected;

 @property (nonatomic,assign) BOOL success;

 @end
GesturePasswordButton.m
 #import "GesturePasswordButton.h"

 #define bounds self.bounds

 @implementation GesturePasswordButton
 @synthesize selected;
 @synthesize success;

 - (id)initWithFrame:(CGRect)frame
 {
     self = [super initWithFrame:frame];
     if (self) {
         // Initialization code
         success=YES;
         [self setBackgroundColor:[UIColor clearColor]];
     }
     return self;
 }

 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
     // Drawing code
     CGContextRef context = UIGraphicsGetCurrentContext();

     if (selected) {
         if (success) {
             CGContextSetRGBStrokeColor(context, /.f, /.f, /.f,);//线条颜色
             CGContextSetRGBFillColor(context,/.f, /.f, /.f,);
         }
         else {
             CGContextSetRGBStrokeColor(context, /.f, /.f, /.f,);//线条颜色
             CGContextSetRGBFillColor(context,/.f, /.f, /.f,);
         }
         CGRect frame = CGRectMake(bounds.size.width/-bounds.size.width/+, bounds.size.height/-bounds.size.height/, bounds.size.width/, bounds.size.height/);

         CGContextAddEllipseInRect(context,frame);
         CGContextFillPath(context);
     }
     else{
         CGContextSetRGBStrokeColor(context, ,,,);//线条颜色
     }

     CGContextSetLineWidth(context,);
     CGRect frame = CGRectMake(, , bounds.size.width-, bounds.size.height-);
     CGContextAddEllipseInRect(context,frame);
     CGContextStrokePath(context);
     if (success) {
         CGContextSetRGBFillColor(context,/.f, /.f, /.f,0.3);
     }
     else {
         CGContextSetRGBFillColor(context,/.f, /.f, /.f,0.3);
     }
     CGContextAddEllipseInRect(context,frame);
     if (selected) {
         CGContextFillPath(context);
     }

 }

 @end

五:前面的步骤都准备好了之后,我们就需要在控制器里面实现相应的代码

GesturePasswordController.h
 #import <UIKit/UIKit.h>
 #import "TentacleView.h"
 #import "GesturePasswordView.h"

 @interface GesturePasswordController : UIViewController <VerificationDelegate,ResetDelegate,GesturePasswordDelegate>

 - (void)clear;

 - (BOOL)exist;

 @end
GesturePasswordController.m
 #import <Security/Security.h>
 #import <CoreFoundation/CoreFoundation.h>

 #import "GesturePasswordController.h"

 #import "KeychainItemWrapper/KeychainItemWrapper.h"

 @interface GesturePasswordController ()

 @property (nonatomic,strong) GesturePasswordView * gesturePasswordView;

 @end

 @implementation GesturePasswordController {
     NSString * previousString;
     NSString * password;
 }

 @synthesize gesturePasswordView;

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
 {
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
     if (self) {
         // Custom initialization
     }
     return self;
 }

 - (void)viewDidLoad
 {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     previousString = [NSString string];
     KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil];
     password = [keychin objectForKey:(__bridge id)kSecValueData];
     if ([password isEqualToString:@""]) {

         [self reset];
     }
     else {
         [self verify];
     }
 }

 - (void)didReceiveMemoryWarning
 {
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
 }

 #pragma mark - 验证手势密码
 - (void)verify{
     gesturePasswordView = [[GesturePasswordView alloc]initWithFrame:[UIScreen mainScreen].bounds];
     [gesturePasswordView.tentacleView setRerificationDelegate:self];
     [gesturePasswordView.tentacleView setStyle:];
     [gesturePasswordView setGesturePasswordDelegate:self];
     [self.view addSubview:gesturePasswordView];
 }

 #pragma mark - 重置手势密码
 - (void)reset{
     gesturePasswordView = [[GesturePasswordView alloc]initWithFrame:[UIScreen mainScreen].bounds];
     [gesturePasswordView.tentacleView setResetDelegate:self];
     [gesturePasswordView.tentacleView setStyle:];
 //    [gesturePasswordView.imgView setHidden:YES];
     [gesturePasswordView.forgetButton setHidden:YES];
     [gesturePasswordView.changeButton setHidden:YES];
     [self.view addSubview:gesturePasswordView];
 }

 #pragma mark - 判断是否已存在手势密码
 - (BOOL)exist{
     KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil];
     password = [keychin objectForKey:(__bridge id)kSecValueData];
     if ([password isEqualToString:@""])return NO;
     return YES;
 }

 #pragma mark - 清空记录
 - (void)clear{
     KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil];
     [keychin resetKeychainItem];
 }

 #pragma mark - 改变手势密码
 - (void)change{
 }

 #pragma mark - 忘记手势密码
 - (void)forget{
 }

 - (BOOL)verification:(NSString *)result{
     if ([result isEqualToString:password]) {
         [gesturePasswordView.state setTextColor:[UIColor colorWithRed:/.f green:/.f blue:/.f alpha:]];
         [gesturePasswordView.state setText:@"输入正确"];
         //[self presentViewController:(UIViewController) animated:YES completion:nil];
         return YES;
     }
     [gesturePasswordView.state setTextColor:[UIColor redColor]];
     [gesturePasswordView.state setText:@"手势密码错误"];
     return NO;
 }

 - (BOOL)resetPassword:(NSString *)result{
     if ([previousString isEqualToString:@""]) {
         previousString=result;
         [gesturePasswordView.tentacleView enterArgin];
         [gesturePasswordView.state setTextColor:[UIColor colorWithRed:/.f green:/.f blue:/.f alpha:]];
         [gesturePasswordView.state setText:@"请验证输入密码"];
         return YES;
     }
     else {
         if ([result isEqualToString:previousString]) {
             KeychainItemWrapper * keychin = [[KeychainItemWrapper alloc]initWithIdentifier:@"Gesture" accessGroup:nil];
             [keychin setObject:@"<帐号>" forKey:(__bridge id)kSecAttrAccount];
             [keychin setObject:result forKey:(__bridge id)kSecValueData];
             //[self presentViewController:(UIViewController) animated:YES completion:nil];
             [gesturePasswordView.state setTextColor:[UIColor colorWithRed:/.f green:/.f blue:/.f alpha:]];
             [gesturePasswordView.state setText:@"已保存手势密码"];
             return YES;
         }
         else{
             previousString =@"";
             [gesturePasswordView.state setTextColor:[UIColor redColor]];
             [gesturePasswordView.state setText:@"两次密码不一致,请重新输入"];
             return NO;
         }
     }
 }

 /*
 #pragma mark - Navigation

 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 {
     // Get the new view controller using [segue destinationViewController].
     // Pass the selected object to the new view controller.
 }
 */

六:最终运行效果如下

iOS开发——高级技术&密码锁功能的实现  iOS开发——高级技术&密码锁功能的实现

 
上一篇:java设计模式4——原型模式


下一篇:Kubernetes实战 - 从零开始搭建微服务 - 1.5 提高可用性-发布多节点的Node/Express网络应用程序