IOS- high imitation Alipay gesture unlock (squares)

Based on the first part of the TouchID fingerprint unlock technical text, and then practice a way to unlock the door: Unlock unlock

In some scenarios involving personal privacy, it is necessary to consider the security of users.

IOS- high imitation Alipay gesture unlock (squares)

First, we first analyze the realization process, first we need to look at the implementation process roughly:
1 create squares page (page and click gesture password) and slides
2 squares in the process of button button state change, and create a path from the implementation, in the process of sliding line drawing
3 to create squares indicator small map
4 will be well defined and view squared squares indicator view is added to the gesture password interface controller
5 to realize the enumeration by gesture gesture password corresponding to the operation.

1 create a grid interface ZLGestureLockView.

The distribution of 3×3 1.1 squares controls, we can customize the view (including the 3×3 button), select the image and normal image can be replaced by the default button.

#pragma mark - initializer - (instancetype) initWithFrame: (CGRect frame) {self = [super initWithFrame:frame]; if (self) {[self initSubviews]}; return self;} / / sub view - (void) initSubviews initialization [UIColor {self.backgroundColor = clearColor]; UIPanGestureRecognizer = *pan [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector (pan:)]; [self addGestureRecognizer:pan]; / / create Sudoku 9 button for (NSInteger I = 0; I 9; < i++) {UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.userInteractionEnabled = NO; [btn setImage:[UIImage imageNamed:@ gesture_normal forState:UIControlStateNormal] [btn setImage:[UIImage image]; Named:@ "gesture_selected" forState:UIControlStateSelected] [self; addSubview:btn]; btn.tag = I + 1;}} / / why cloth Bureau controls in this method, because only call this method that determines the size of the parent control - (void) layoutSubviews [super NSUInteger count {layoutSubviews]; int = self.subviews.count; cols = 3; / / total column the number of CGFloat x = 0, y = 0, w = 0, H = 0; if (Screen_Width = = 320) {w = 50; H = 50;} else {w = 58; H = 58;} CGFloat (self.bounds.size.width = margin - cols * W) / (cols + 1); / / spacing CGFloat col CGFloat = 0; row = 0; for (int i = 0; I < count; i++) {col = I% cols = I; row / cols; X = ma Rgin + (w+margin) *col; y = margin + *row (w+margin); if (Screen_Height = = 480) {/ / adapter 4 inch screen y = (W + margin) * row;}else {y = margin + (W + margin) * row;} UIButton *btn = self.subviews[i]; btn.frame = CGRectMake (x y, W, H);}}

1.2 define a display method

Note: we are in the process of determining the password in the process is based on the layout button before the definition of the button tag value for string splicing, password value is achieved through the proxy.

@protocol ZLGestureLockDelegate < NSObject> - (void) gestureLockView: (ZLGestureLockView * lockView) drawRectFinished: (NSMutableString * gesturePassword); @end @interface ZLGestureLockView: UIView @property (assign, nonatomic) id< ZLGestureLockDelegate> delegate; @end

2 the realization of the nine buttons and the button is clicked and the change in the process of sliding button, thereby creating a path to achieve the sliding process of the connection, drawing graphics

2.1 defines the member properties of an array type, which is used to hold the button that is clicked

@property (strong, nonatomic) NSMutableArray *selectBtns;
#pragma mark - getter (NSMutableArray *) selectBtns {if ((_selectBtns) {_selectBtns = [NSMutableArray array];} return};})

2.2 create a path to achieve the sliding process of the connection, drawing graphics

Just before / / call this method will draw something empty re - (void) drawRect: (CGRect rect) {if (_selectBtns.count = = 0) / / return; all the selected button line of the center of UIBezierPath *path = [UIBezierPath bezierPath]; if (self.userInteractionEnabled) {[[UIColor} else {[[UIColor yellowColor] set]; orangeColor] set] for;} (int i = 0; I < self.selectBtns.count; I + +) {UIButton *btn = self.selectBtns[i]; if (I = = 0) {[path moveToPoint:btn.center]} {else; / / set the starting point [path addLineToPoint:btn.center] [path addLineToPoint:_currentPoint];}}; [UIColorFromRGB (0xffc8ad) set]; path.lineWidth = 6; P Ath.lineJoinStyle = kCGLineCapRound; path.lineCapStyle = kCGLineCapRound; [path stroke];}

2.3 start touch, gesture password after the completion of the completion of the password to enter the password and callback

#pragma mark - action Pan - (void) pan: (UIPanGestureRecognizer * pan) {_currentPoint = [pan locationInView:self]; [self setNeedsDisplay]; for (UIButton *button in self.subviews (CGRectContainsPoint) {if (button.frame, _currentPoint) & & button.selected = = NO) {button.selected = YES; [self.selectBtns addObject:button];}} [self (layoutIfNeeded]; if pan.state = = UIGestureRecognizerStateEnded) {/ / save password *gesturePwd = @ "NSMutableString".MutableCopy; for (UIButton *button in self.selectBtns [gesturePwd appendFormat:@) {%ld, button.tag-1]; button.selected = NO;} [self.selectBtns removeA LlObjects]; / / gesture password after drawing back the if ([self.delegate respondsToSelector:@selector (gestureLockView:drawRectFinished:)] [self.delegate) {gestureLockView:self drawRectFinished:gesturePwd]}}};

3 create a grid indicator ZLGestureLockIndicator

3.1 the control of the distribution is 3X3, we can also customize the view (including 3×3 buttons)

#pragma mark - initializer - (instancetype) initWithFrame: (CGRect frame) {if (self = [super initWithFrame:frame]) {[self initSubviews]}; return self;} / / sub - (void) initSubviews view initialization {/ / create 9 buttons for (int i = 0; I 9; < i++) {UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.userInteractionEnabled = NO; [btn setImage:[UIImage imageNamed:@ gesture_indicator_normal forState:UIControlStateNormal] [btn setImage:[UIImage imageNamed:@]; gesture_indicator_selected [self addSubview:btn]; [self.btns forState:UIControlStateSelected]; addObject:btn];}} - {(void) layoutSubviews [super layoutSubviews]; NSUInteger Co Unt int = self.subviews.count; cols = 3; / / the total number of columns CGFloat, x = 0, y = 0, w = 9, H = 9; //bounds = CGFloat margin (self.bounds.size.width - cols * W) / (cols + 1); / / COL CGFloat distance CGFloat = 0; row = 0; for (int i i = 0; < count; i++) {col = i%cols; row = i/cols; X = margin + *col (w+margin); y = margin + *row (w+margin); UIButton *btn = self.subviews[i]; btn.frame = CGRectMake (x, y, W, H);}}

The 3.2 member property for the definition of the array type, click the button in the ninth house is Getu (and narrow big squares were selected to show)

@property (nonatomic, strong) NSMutableArray *btns;
#pragma mark - getter (NSMutableArray *) BTNs {if ((_btns) {_btns = [NSMutableArray array];} return};})

3.3 return path

- (void) setGesturePassword: (NSString *) gesturePassword;
#pragma mark - public - (void) setGesturePassword: (NSString * gesturePassword) {if (gesturePassword.length = = 0) {for (UIButton *button in self.btns) {button.selected}} = NO; return; for (int i = 0; I < gesturePassword.length; i++) {NSString *s = [gesturePassword substringWithRange:NSMakeRange (I, 1)] [self.btns[s.integerValue]; setSelected:YES];}}

4 will be a good definition of the grid view and the grid indicator view added to the gesture password interface controller ZLGestureLockViewController

4.1 load to controller

Figure ZLGestureLockIndicator small squares indicator / / *gestureLockIndicator = [[ZLGestureLockIndicator (alloc]initWithFrame:CGRectMake (self.view.frame.size.width - 60) * 0.5, 110, 60, 60)]; [self.view addSubview:gestureLockIndicator]; self.gestureLockIndicator = gestureLockIndicator; / / Jiugongge gesture password page ZLGestureLockView *gestureLockView = [[ZLGestureLockView alloc]initWithFrame:CGRectMake (0, self.view.frame.size.height - self.view.frame.size.width - 60 - btnH, self.view.frame.size.width, self.view.frame.size.width)]; gestureLockView.delegate [self.view = self; addSubview:gestureLockView] = gestureLockView; self.gestureLockView;

4.2 create gesture password enumeration

#import < UIKit/UIKit.h> typedef; NS_ENUM (NSInteger, ZLUnlockType) {ZLUnlockTypeCreatePsw / / ZLUnlockTypeValidatePsw / / create gesture password check gesture password: UIViewController + ZLGestureLockViewController}; @interface (void deleteGesturesPassword); / / delete gesture password + (NSString * gesturesPassword); / / get the gesture password - (instancetype) initWithUnlockType: (ZLUnlockType) unlockType; @end
/ / create gesture password @property (nonatomic, copy) NSString *lastGesturePsw @property (nonatomic ZLUnlockType unlockType);
#pragma mark - inint - (instancetype) initWithUnlockType: (ZLUnlockType unlockType) {if (self = [super init]) {_unlockType = unlockType;} return self;} #pragma mark - viewDidLoad - viewDidLoad (void) {[super viewDidLoad] = [UIColor; self.view.backgroundColor whiteColor]; [self setupMainUI]; self.gestureLockView.delegate = self; self.resetPswBtn.hidden = YES; switch (_unlockType) ZLUnlockTypeCreatePsw: {case {self.gestureLockIndicator.hidden = NO; self.otherAcountBtn.hidden = self.forgetPswBtn.hidden = self.nameLabel.hidden = self.headIcon.hidden = YES;} ZLUnlockTypeValidatePsw: {self.ges break; case TureLockIndicator.hidden = YES; self.otherAcountBtn.hidden = self.forgetPswBtn.hidden = self.nameLabel.hidden = self.headIcon.hidden = NO; break default: break;};}}
#pragma mark - ZLgestureLockViewDelegate - (void) gestureLockView: (ZLGestureLockView * lockView) drawRectFinished: (NSMutableString * gesturePassword) {switch (_unlockType case ZLUnlockTypeCreatePsw:) {/ / create gesture password {[self createGesturesPassword:gesturePassword];} break case ZLUnlockTypeValidatePsw:; / / check gesture password {[self validateGesturesPassword:gesturePassword]; break default: break;};}}

4.3 create gesture password and save gesture password

#pragma mark - (void) deleteGesturesPassword + {[[NSUserDefaults standardUserDefaults] removeObjectForKey:GesturesPassword]; [[NSUserDefaults standardUserDefaults] synchronize];} + (void) addGesturesPassword: (NSString *) gesturesPassword standardUserDefaults] setObject:gesturesPassword {[[NSUserDefaults forKey:GesturesPassword]; [[NSUserDefaults standardUserDefaults] synchronize];} + (NSString *) gesturesPassword [[NSUserDefaults standardUserDefaults] {return objectForKey:GesturesPassword];}
#pragma mark - private / / create a gesture password - (void) createGesturesPassword: (NSMutableString * gesturesPassword) {if (self.lastGesturePsw.length = = 0) {if (gesturesPassword.length < 4) {self.statusLabel.text = @ "connected to at least four, please input again"; [self shakeAnimationForView:self.statusLabel]; return if;} ({self.resetPswBtn.hidden = self.resetPswBtn.hidden = = YES) NO;} self.lastGesturePsw = gesturesPassword; [self.gestureLockIndicator setGesturePassword: gesturesPassword]; self.statusLabel.text = @ "please draw the gesture password again; return; if ([self.lastGesturePsw isEqualToString:gesturesPassword]) {} [self dismissViewControllerAnimated:YES completion:^{/ / / / draw the successful save gesture password [ZLGestureLockViewController addGesturesPassword:gesturesPassword];}];}else {self.statusLabel.text = @ "is not consistent with the rendering time, please re draw" [self; shakeAnimationForView:self.statusLabel];}}

4.4 verify gesture password and password error input logic

Demand for each product is not the same, I can enter the error here five times and jitter tips, or exit the login again

Verify / gesture password - (void) validateGesturesPassword: (NSMutableString * gesturesPassword) {static NSInteger errorCount = 5; if ([gesturesPassword isEqualToString:[ZLGestureLockViewController gesturesPassword]]) [self dismissViewControllerAnimated:YES completion:^{{errorCount = 5;}];} else {if (errorCount - 1 = = 0) {/ / you have the wrong five times! Exit login! UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@ "message:@" gesture password has expired "please re login" delegate:self cancelButtonTitle:nil otherButtonTitles:@ "again landing", nil]; [alertView show]; errorCount = 5; self.statusLabel.text = return;} [NSString stringWithFormat:@ "wrong password, you can enter%ld, --errorCount]; [self shakeAnimationForView:self.statusLabel];}}
/ / Animation - (void) shakeAnimationForView: jitter (UIView * view) {CALayer *viewLayer = view.layer; CGPoint = position viewLayer.position; CGPoint left = CGPointMake (position.x - 10, position.y); CGPoint right = CGPointMake (position.x + 10, position.y); CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@ [animation setTimingFunction:[CAMediaTimingFunction "position"]; functionWithName:kCAMediaTimingFunctionEaseInEaseOut]] [animation; setFromValue:[NSValue valueWithCGPoint:left]]; [animation setToValue:[NSValue valueWithCGPoint:right]]; [animation setAutoreverses:YES]; / / [animation setDuration:0.08] [animation setRepeatCount:3] smooth end; [viewLayer; addAnimation:animation ForKey:nil];}
#pragma mark - UIAlertViewDelegate - (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex NSLog (@ {/ / re landing "re landing");}

4.5 other button events at the bottom

In particular, to re draw the button, remember the need to create the gesture password set to empty

#pragma mark - Anction / / click the other button click event account login button - (void) otherAccountLogin: (ID sender) {NSLog (@ "%s", __FUNCTION__);} / / click to draw the button - (void) resetGesturePassword: (ID sender) {NSLog (@ "%s", __FUNCTION__); self.lastGesturePsw = nil; self.statusLabel.text = @ "please draw the gesture password; self.resetPswBtn.hidden = YES; [self.gestureLockIndicator" setGesturePassword:@ "];} / / click forgot password gesture button - (void) forgetGesturesPassword: (ID sender) {NSLog (@"%s ", __FUNCTION__);}

5 by hand gestures to achieve the corresponding implementation of gesture password

ZLGestureLockViewController *vc / / create gesture password = [[ZLGestureLockViewController alloc] initWithUnlockType:ZLUnlockTypeCreatePsw]; [self presentViewController:vc animated:YES completion:nil];
/ / check ([ZLGestureLockViewController gesturesPassword].length > if gesture password; 0) {ZLGestureLockViewController *vc = [[ZLGestureLockViewController alloc] initWithUnlockType:ZLUnlockTypeValidatePsw]; [self presentViewController:vc animated:YES completion:nil];} else {UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@ "has not set a gesture password" delegate:nil cancelButtonTitle:nil otherButtonTitles:@ "OK" nil]; [alertView show];}
[ZLGestureLockViewController deleteGesturesPassword] / / delete gesture password;

OK, you can now look at the effect of it!

IOS- high imitation Alipay gesture unlock (squares)
gesture unlock.Gif