diff --git a/KKGestureLockView.xcodeproj/project.pbxproj b/KKGestureLockView.xcodeproj/project.pbxproj index 143da97..1ec0a50 100644 --- a/KKGestureLockView.xcodeproj/project.pbxproj +++ b/KKGestureLockView.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ A399B46A17AF507400ADF304 /* gesture_node_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = A399B46617AF507400ADF304 /* gesture_node_selected.png */; }; A399B46C17AF8FD300ADF304 /* gesture_background.png in Resources */ = {isa = PBXBuildFile; fileRef = A399B46B17AF8FD300ADF304 /* gesture_background.png */; }; A399B47017AF997100ADF304 /* KKGestureLockView.m in Sources */ = {isa = PBXBuildFile; fileRef = A399B46F17AF997100ADF304 /* KKGestureLockView.m */; }; + CC657ADA186D9F2A0009C58E /* gesture_node_error@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CC657AD9186D9F2A0009C58E /* gesture_node_error@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -50,6 +51,7 @@ A399B46B17AF8FD300ADF304 /* gesture_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gesture_background.png; sourceTree = ""; }; A399B46E17AF997100ADF304 /* KKGestureLockView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KKGestureLockView.h; sourceTree = ""; }; A399B46F17AF997100ADF304 /* KKGestureLockView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KKGestureLockView.m; sourceTree = ""; }; + CC657AD9186D9F2A0009C58E /* gesture_node_error@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "gesture_node_error@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -110,6 +112,7 @@ A399B44317AED01800ADF304 /* Supporting Files */ = { isa = PBXGroup; children = ( + CC657AD9186D9F2A0009C58E /* gesture_node_error@2x.png */, A399B46B17AF8FD300ADF304 /* gesture_background.png */, A399B46317AF507400ADF304 /* gesture_node_normal@2x.png */, A399B46417AF507400ADF304 /* gesture_node_normal.png */, @@ -191,6 +194,7 @@ A399B44F17AED01800ADF304 /* Default.png in Resources */, A399B45117AED01800ADF304 /* Default@2x.png in Resources */, A399B45317AED01800ADF304 /* Default-568h@2x.png in Resources */, + CC657ADA186D9F2A0009C58E /* gesture_node_error@2x.png in Resources */, A399B45917AED01800ADF304 /* KKViewController.xib in Resources */, A399B46717AF507400ADF304 /* gesture_node_normal@2x.png in Resources */, A399B46817AF507400ADF304 /* gesture_node_normal.png in Resources */, @@ -333,6 +337,7 @@ A399B45E17AED01800ADF304 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/KKGestureLockView/KKViewController.h b/KKGestureLockView/KKViewController.h old mode 100644 new mode 100755 diff --git a/KKGestureLockView/KKViewController.m b/KKGestureLockView/KKViewController.m index 26ed3cc..6cca133 100644 --- a/KKGestureLockView/KKViewController.m +++ b/KKGestureLockView/KKViewController.m @@ -8,15 +8,20 @@ #import "KKViewController.h" @interface KKViewController () - +@property (nonatomic, assign) NSUInteger tryTimes; +@property (nonatomic, strong) NSString *firstPasscode; @end @implementation KKViewController +- (void)viewWillAppear:(BOOL)animated +{ + self.tryTimes = 0; +} + - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor whiteColor]; self.lockView.normalGestureNodeImage = [UIImage imageNamed:@"gesture_node_normal.png"]; self.lockView.selectedGestureNodeImage = [UIImage imageNamed:@"gesture_node_selected.png"]; @@ -24,6 +29,8 @@ - (void)viewDidLoad self.lockView.lineWidth = 12; self.lockView.delegate = self; self.lockView.contentInsets = UIEdgeInsetsMake(150, 20, 100, 20); + //if set autoResetSelectionState to NO, you need to manage the selection state by yourself. + self.lockView.autoResetSelectionState = NO; } - (void)didReceiveMemoryWarning @@ -32,13 +39,47 @@ - (void)didReceiveMemoryWarning // Dispose of any resources that can be recreated. } +- (void)reset:(KKGestureLockView *)gestureLockView +{ + [gestureLockView resetSelectionState]; + gestureLockView.lineColor = [[UIColor orangeColor] colorWithAlphaComponent:0.3]; + gestureLockView.selectedGestureNodeImage = [UIImage imageNamed:@"gesture_node_selected.png"]; + gestureLockView.userInteractionEnabled = YES; +} - (void)gestureLockView:(KKGestureLockView *)gestureLockView didBeginWithPasscode:(NSString *)passcode{ - NSLog(@"%@",passcode); + NSLog(@"passcode1: %@", passcode); } - (void)gestureLockView:(KKGestureLockView *)gestureLockView didEndWithPasscode:(NSString *)passcode{ - NSLog(@"%@",passcode); -} + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" + message:@"" + delegate:nil + cancelButtonTitle:@"确定" + otherButtonTitles:nil]; + NSLog(@"passcode2: %@", passcode); + if (!gestureLockView.autoResetSelectionState) { + gestureLockView.userInteractionEnabled = NO; + } + if (self.tryTimes == 0) { + self.firstPasscode = passcode; + alert.message = [NSString stringWithFormat:@"第一次输入的密码是:\n%@", passcode]; + [alert show]; + [self reset:gestureLockView]; + } else { + if ([passcode isEqualToString:self.firstPasscode]) { + alert.message = @"两次密码一样!"; + [alert show]; + [self reset:gestureLockView]; + } else { + alert.message = @"两次密码不一样!"; + [alert show]; + UIImage *selectedImage = [UIImage imageNamed:@"gesture_node_error"]; + [gestureLockView redrawOnlySelectionWithLineColor:[UIColor redColor] selectedImage:selectedImage]; + [self performSelector:@selector(reset:) withObject:gestureLockView afterDelay:1]; + } + } + self.tryTimes += 1; +} @end diff --git a/KKGestureLockView/Source/KKGestureLockView.h b/KKGestureLockView/Source/KKGestureLockView.h index eafd44a..128c47e 100644 --- a/KKGestureLockView/Source/KKGestureLockView.h +++ b/KKGestureLockView/Source/KKGestureLockView.h @@ -17,6 +17,8 @@ - (void)gestureLockView:(KKGestureLockView *)gestureLockView didEndWithPasscode:(NSString *)passcode; - (void)gestureLockView:(KKGestureLockView *)gestureLockView didCanceledWithPasscode:(NSString *)passcode; + + @end @interface KKGestureLockView : UIView @@ -32,7 +34,22 @@ @property (nonatomic, strong, readonly) UIView *contentView;//the container of the gesture notes @property (nonatomic, assign) UIEdgeInsets contentInsets; +//autoResetSelectionState desides whether to reset the selection state to origin. +@property (nonatomic, assign) BOOL autoResetSelectionState; //default is YES @property (nonatomic, weak) id delegate; + +- (void)resetSelectionState; +/* + Important: redrawOnlySelectionWithLineColor has side-effect that it will modify + the lineColor and selectedImage, so you should reset gestureLockView's + lineColor and selectedImage to original one manually. + */ +- (void)redrawOnlySelectionWithLineColor:(UIColor *)lineColor selectedImage:(UIImage *)selectedImage; + +/* + drawSelectionWithPassCode helps to draw passcode on gestureLockView, e.g. thumbnailGestureLockView(手势密码的缩略图) + */ +- (void)drawSelectionWithPassCode:(NSString *)passCode; @end diff --git a/KKGestureLockView/Source/KKGestureLockView.m b/KKGestureLockView/Source/KKGestureLockView.m index 817e390..05d6c44 100644 --- a/KKGestureLockView/Source/KKGestureLockView.m +++ b/KKGestureLockView/Source/KKGestureLockView.m @@ -73,9 +73,9 @@ - (void)_lockViewInitialize{ self.contentView = [[UIView alloc] initWithFrame:UIEdgeInsetsInsetRect(self.bounds, self.contentInsets)]; self.contentView.backgroundColor = [UIColor clearColor]; [self addSubview:self.contentView]; - + self.buttonSize = CGSizeMake(kNodeDefaultWidth, kNodeDefaultHeight); - + self.normalGestureNodeImage = [self imageWithColor:[UIColor greenColor] size:self.buttonSize]; self.selectedGestureNodeImage = [self imageWithColor:[UIColor redColor] size:self.buttonSize]; @@ -85,8 +85,17 @@ - (void)_lockViewInitialize{ self.selectedButtons = [NSMutableArray array]; self.trackedLocationInContentView = CGPointMake(kTrackedLocationInvalidInContentView, kTrackedLocationInvalidInContentView); + self.autoResetSelectionState = YES; } +- (NSString *)generatePassCode +{ + NSMutableArray *passCodeArray = [NSMutableArray array]; + for (UIButton *button in self.selectedButtons) { + [passCodeArray addObject:[@(button.tag) stringValue]]; + } + return [passCodeArray componentsJoinedByString:@","]; +} #pragma mark - #pragma mark UIView Overrides @@ -185,37 +194,30 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ if ([self.selectedButtons count] > 0) { if (_delegateFlags.didEndWithPasscode) { - NSMutableArray *passcodeArray = [NSMutableArray array]; - for (UIButton *button in self.selectedButtons) { - [passcodeArray addObject:[NSString stringWithFormat:@"%d",button.tag]]; - } - - [self.delegate gestureLockView:self didEndWithPasscode:[passcodeArray componentsJoinedByString:@","]]; + [self.delegate gestureLockView:self didEndWithPasscode:[self generatePassCode]]; } } - - for (UIButton *button in self.selectedButtons) { - button.selected = NO; - } - [self.selectedButtons removeAllObjects]; - self.trackedLocationInContentView = CGPointMake(kTrackedLocationInvalidInContentView, kTrackedLocationInvalidInContentView); - [self setNeedsDisplay]; - + if (self.autoResetSelectionState) { + [self resetSelectionState]; + } } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{ if ([self.selectedButtons count] > 0) { if (_delegateFlags.didCanceled) { - NSMutableArray *passcodeArray = [NSMutableArray array]; - for (UIButton *button in self.selectedButtons) { - [passcodeArray addObject:[NSString stringWithFormat:@"%d",button.tag]]; - } - - [self.delegate gestureLockView:self didCanceledWithPasscode:[passcodeArray componentsJoinedByString:@","]]; + [self.delegate gestureLockView:self didCanceledWithPasscode:[self generatePassCode]]; } } - + + if (self.autoResetSelectionState) { + [self resetSelectionState]; + } +} + +#pragma pulic methods +- (void)resetSelectionState +{ for (UIButton *button in self.selectedButtons) { button.selected = NO; } @@ -224,6 +226,31 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{ [self setNeedsDisplay]; } +- (void)redrawOnlySelectionWithLineColor:(UIColor *)lineColor selectedImage:(UIImage *)selectedImage +{ + self.lineColor = lineColor; + self.trackedLocationInContentView = CGPointMake(kTrackedLocationInvalidInContentView, kTrackedLocationInvalidInContentView); + [self setSelectedGestureNodeImage:selectedImage]; + [self setNeedsDisplay]; +} + +- (void)drawSelectionWithPassCode:(NSString *)passCode +{ + NSArray *passCodeArray = [passCode componentsSeparatedByString:@","]; + if (passCodeArray.count <= 0) return; + //clean state first + [self resetSelectionState]; + for (NSString *passCodeUnit in passCodeArray) { + NSInteger buttonTag = [passCodeUnit integerValue]; + if (buttonTag >= 0 && buttonTag < self.buttons.count) { + UIButton *button = self.buttons[buttonTag]; + button.selected = YES; + [self.selectedButtons addObject:button]; + } + } + [self setNeedsDisplay]; +} + #pragma mark - #pragma mark Accessors - (void)setNormalGestureNodeImage:(UIImage *)normalGestureNodeImage{ @@ -264,7 +291,7 @@ - (void)setDelegate:(id)delegate{ _delegateFlags.didBeginWithPasscode = [delegate respondsToSelector:@selector(gestureLockView:didBeginWithPasscode:)]; _delegateFlags.didEndWithPasscode = [delegate respondsToSelector:@selector(gestureLockView:didEndWithPasscode:)]; - _delegateFlags.didCanceled = [delegate respondsToSelector:@selector(gestureLockViewCanceled:)]; + _delegateFlags.didCanceled = [delegate respondsToSelector:@selector(gestureLockView:didCanceledWithPasscode:)]; } - (void)setNumberOfGestureNodes:(NSUInteger)numberOfGestureNodes{ diff --git a/KKGestureLockView/gesture_node_error@2x.png b/KKGestureLockView/gesture_node_error@2x.png new file mode 100644 index 0000000..90e55a9 Binary files /dev/null and b/KKGestureLockView/gesture_node_error@2x.png differ diff --git a/README.md b/README.md index 219ca9c..2732aae 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ KKGestureLockView是一个非常方便使用的Gesture Lock控件,只需要简 ##用法 -控件的源码在`KKGestureLockView/Source`目录下,且自带了一个仿支付宝解锁界面的例子(例子的图片资源取自支付宝app解压缩后的资源图片): +控件的源码在`KKGestureLockView/Source`目录下,且自带了一个仿支付宝解锁界面的简单例子(例子的图片资源取自支付宝app解压缩后的资源图片): self.lockView.normalGestureNodeImage = [UIImage imageNamed:@"gesture_node_normal.png"]; self.lockView.selectedGestureNodeImage = [UIImage imageNamed:@"gesture_node_selected.png"]; @@ -21,6 +21,11 @@ KKGestureLockView是一个非常方便使用的Gesture Lock控件,只需要简 self.lockView.delegate = self; self.lockView.contentInsets = UIEdgeInsetsMake(150, 20, 100, 20); +如果要自己控制绘制手势之后的节点的显示控制,比如, 如果手势错误需要将节点、节点间的线都变成红色,那么可以这样做(具体用法请参考KKViewController.m)里面的例子: + + UIImage *selectedImage = [UIImage imageNamed:@"gesture_node_error"]; + [self.lockView redrawOnlySelectionWithLineColor:[UIColor redColor] selectedImage:selectedImage]; + 一般情况下9个节点便够用了,当然如果你想多弄些节点也不是不可以: