Skip to content
This repository has been archived by the owner on May 13, 2019. It is now read-only.

freetext supports #20

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions example/KKPasscodeLock/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ - (void)applicationDidBecomeActive:(UIApplication *)application
if ([[KKPasscodeLock sharedLock] isPasscodeRequired]) {
KKPasscodeViewController *vc = [[KKPasscodeViewController alloc] initWithNibName:nil bundle:nil];
vc.mode = KKPasscodeModeEnter;
vc.inputMode = KKPasscodeInputModeFreeText;
vc.delegate = self;

dispatch_async(dispatch_get_main_queue(),^ {
Expand Down
4 changes: 4 additions & 0 deletions example/KKPasscodeLock/RootViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

@implementation RootViewController

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

- (IBAction)showPasscode:(id)sender {

SettingsViewController* settingsViewController = [[SettingsViewController alloc]
Expand Down
1 change: 1 addition & 0 deletions example/KKPasscodeLock/SettingsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
if (indexPath.section == 0) {
KKPasscodeSettingsViewController *vc = [[KKPasscodeSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
vc.delegate = self;
vc.inputMode = KKPasscodeInputModeFreeText;
[self.navigationController pushViewController:vc animated:YES];
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/KKPasscodeSettingsViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@

// whatever the erase data option is turned on or off
BOOL _eraseDataOn;

KKPasscodeInputMode _inputMode;
}

@property (nonatomic, unsafe_unretained) id <KKPasscodeSettingsViewControllerDelegate> delegate;
@property (nonatomic, assign) KKPasscodeInputMode inputMode;

@end
4 changes: 4 additions & 0 deletions src/KKPasscodeSettingsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ @implementation KKPasscodeSettingsViewController


@synthesize delegate = _delegate;
@synthesize inputMode = _inputMode;

#pragma mark -
#pragma mark UIViewController methods
Expand Down Expand Up @@ -191,6 +192,8 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)
} else {
vc.mode = KKPasscodeModeSet;
}

vc.inputMode = _inputMode;

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];

Expand All @@ -216,6 +219,7 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)
vc.delegate = self;

vc.mode = KKPasscodeModeChange;
vc.inputMode = _inputMode;

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];

Expand Down
19 changes: 17 additions & 2 deletions src/KKPasscodeViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ enum {
};
typedef NSUInteger KKPasscodeMode;

// the input mode
enum {
/**
* 4-digit passcode input
*/
KKPasscodeInputModeDefault = 0,

/**
* Free-text passcode input
*/
KKPasscodeInputModeFreeText = 1
};
typedef NSUInteger KKPasscodeInputMode;


@class KKPasscodeViewController;

Expand Down Expand Up @@ -87,7 +101,7 @@ typedef NSUInteger KKPasscodeMode;
// array of passcode entry text fields
NSMutableArray* _textFields;

NSMutableArray* _boxes;
NSMutableArray* _boxes;

UITableView* _enterPasscodeTableView;
UITextField* _enterPasscodeTextField;
Expand All @@ -100,6 +114,7 @@ typedef NSUInteger KKPasscodeMode;

// readwrite override for passlock mode
KKPasscodeMode _mode;
KKPasscodeInputMode _inputMode;

// whatever the passcode lock is turned on or off
BOOL _passcodeLockOn;
Expand All @@ -114,7 +129,7 @@ typedef NSUInteger KKPasscodeMode;

@property (nonatomic, unsafe_unretained) id <KKPasscodeViewControllerDelegate> delegate;
@property (nonatomic, assign) KKPasscodeMode mode;

@property (nonatomic, assign) KKPasscodeInputMode inputMode;

@end

136 changes: 96 additions & 40 deletions src/KKPasscodeViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ @interface KKPasscodeViewController (Private)

- (UITextField*)passcodeTextField;
- (NSArray*)boxes;
- (CGRect)textFieldFrame;
- (UIView*)headerViewForTextField:(UITextField*)textField;
- (void)moveToNextTableView;
- (void)moveToPreviousTableView;
Expand All @@ -45,6 +46,7 @@ @implementation KKPasscodeViewController

@synthesize delegate = _delegate;
@synthesize mode = _mode;
@synthesize inputMode = _inputMode;
@synthesize isSmallLandscape;

#pragma mark -
Expand Down Expand Up @@ -92,20 +94,48 @@ - (void)viewWillAppear:(BOOL)animated
_passcodeLockOn = [[KKKeychain getStringForKey:@"passcode_on"] isEqualToString:@"YES"];
_eraseData = [[KKPasscodeLock sharedLock] eraseOption] && [[KKKeychain getStringForKey:@"erase_data_on"] isEqualToString:@"YES"];

BOOL hiddenTextField = (_inputMode == KKPasscodeInputModeDefault);
CGRect textFieldFrame = [self textFieldFrame];
UIKeyboardType keyboardType = UIKeyboardTypeDefault;
if (_inputMode == KKPasscodeInputModeDefault) {
keyboardType = UIKeyboardTypeNumberPad;
}

_enterPasscodeTextField = [[UITextField alloc] init];
_enterPasscodeTextField.delegate = self;
_enterPasscodeTextField.keyboardType = UIKeyboardTypeNumberPad;
_enterPasscodeTextField.hidden = YES;
_enterPasscodeTextField.keyboardType = keyboardType;
_enterPasscodeTextField.hidden = hiddenTextField;
_enterPasscodeTextField.frame = textFieldFrame;
_enterPasscodeTextField.secureTextEntry = YES;
_enterPasscodeTextField.textAlignment = NSTextAlignmentCenter;
_enterPasscodeTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
_enterPasscodeTextField.backgroundColor = [UIColor whiteColor];
_enterPasscodeTextField.font = [UIFont boldSystemFontOfSize:20];
_enterPasscodeTextField.borderStyle = UITextBorderStyleRoundedRect;

_setPasscodeTextField = [[UITextField alloc] init];
_setPasscodeTextField.delegate = self;
_setPasscodeTextField.keyboardType = UIKeyboardTypeNumberPad;
_setPasscodeTextField.hidden = YES;
_setPasscodeTextField.keyboardType = keyboardType;
_setPasscodeTextField.hidden = hiddenTextField;
_setPasscodeTextField.frame = textFieldFrame;
_setPasscodeTextField.secureTextEntry = YES;
_setPasscodeTextField.textAlignment = NSTextAlignmentCenter;
_setPasscodeTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
_setPasscodeTextField.backgroundColor = [UIColor whiteColor];
_setPasscodeTextField.font = [UIFont boldSystemFontOfSize:20];
_setPasscodeTextField.borderStyle = UITextBorderStyleRoundedRect;

_confirmPasscodeTextField = [[UITextField alloc] init];
_confirmPasscodeTextField.delegate = self;
_confirmPasscodeTextField.keyboardType = UIKeyboardTypeNumberPad;
_confirmPasscodeTextField.hidden = YES;
_confirmPasscodeTextField.keyboardType = keyboardType;
_confirmPasscodeTextField.hidden = hiddenTextField;
_confirmPasscodeTextField.frame = textFieldFrame;
_confirmPasscodeTextField.secureTextEntry = YES;
_confirmPasscodeTextField.textAlignment = NSTextAlignmentCenter;
_confirmPasscodeTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
_confirmPasscodeTextField.backgroundColor = [UIColor whiteColor];
_confirmPasscodeTextField.font = [UIFont boldSystemFontOfSize:20];
_confirmPasscodeTextField.borderStyle = UITextBorderStyleRoundedRect;

_tableViews = [[NSMutableArray alloc] init];
_textFields = [[NSMutableArray alloc] init];
Expand Down Expand Up @@ -144,6 +174,7 @@ - (void)viewWillAppear:(BOOL)animated
[_textFields addObject:_enterPasscodeTextField];
[_boxes addObject:[self boxes]];
UIView *boxesView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width * 0.5 - 71.0 * kPasscodeBoxesCount * 0.5, 0, 71.0 * kPasscodeBoxesCount, kPasscodeBoxHeight)];
[boxesView addSubview:_enterPasscodeTextField];
boxesView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
for (int i = 0; i < [[_boxes lastObject] count]; i++) {
[boxesView addSubview:[[_boxes lastObject] objectAtIndex:i]];
Expand All @@ -157,6 +188,7 @@ - (void)viewWillAppear:(BOOL)animated
[_textFields addObject:_setPasscodeTextField];
[_boxes addObject:[self boxes]];
UIView *boxesView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width * 0.5 - 71.0 * kPasscodeBoxesCount * 0.5, 0, 71.0 * kPasscodeBoxesCount, kPasscodeBoxHeight)];
[boxesView addSubview:_setPasscodeTextField];
boxesView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
for (int i = 0; i < [[_boxes lastObject] count]; i++) {
[boxesView addSubview:[[_boxes lastObject] objectAtIndex:i]];
Expand All @@ -168,6 +200,7 @@ - (void)viewWillAppear:(BOOL)animated
[_textFields addObject:_confirmPasscodeTextField];
[_boxes addObject:[self boxes]];
UIView *boxesConfirmView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width * 0.5 - 71.0 * kPasscodeBoxesCount * 0.5, 0, 71.0 * kPasscodeBoxesCount, kPasscodeBoxHeight)];
[boxesConfirmView addSubview:_confirmPasscodeTextField];
boxesConfirmView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
for (int i = 0; i < [[_boxes lastObject] count]; i++) {
[boxesConfirmView addSubview:[[_boxes lastObject] objectAtIndex:i]];
Expand All @@ -179,6 +212,7 @@ - (void)viewWillAppear:(BOOL)animated
[_textFields addObject:_enterPasscodeTextField];
[_boxes addObject:[self boxes]];
UIView *boxesView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width * 0.5 - 71.0 * kPasscodeBoxesCount * 0.5, 0, 71.0 * kPasscodeBoxesCount, kPasscodeBoxHeight)];
[boxesView addSubview:_enterPasscodeTextField];
boxesView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
for (int i = 0; i < [[_boxes lastObject] count]; i++) {
[boxesView addSubview:[[_boxes lastObject] objectAtIndex:i]];
Expand Down Expand Up @@ -225,6 +259,9 @@ - (void)viewWillDisappear:(BOOL)animated {
[_confirmPasscodeTextField resignFirstResponder];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark -
#pragma mark Private methods
Expand All @@ -245,9 +282,11 @@ - (void)incrementFailedAttemptsLabel
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

_enterPasscodeTextField.text = @"";
for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
if (_inputMode == KKPasscodeInputModeDefault) {
for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
}

_failedAttemptsCount += 1;
if (_failedAttemptsCount == 1) {
Expand Down Expand Up @@ -298,9 +337,11 @@ - (void)moveToNextTableView
oldTableView.frame.size.width,
oldTableView.frame.size.height);

for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
if (_inputMode == KKPasscodeInputModeDefault) {
for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
}

[UIView beginAnimations:@"" context:nil];
[UIView setAnimationDuration:0.25];
Expand All @@ -323,9 +364,11 @@ - (void)moveToPreviousTableView
UITableView *newTableView = [_tableViews objectAtIndex:_currentPanel];
newTableView.frame = CGRectMake(oldTableView.frame.origin.x - self.view.bounds.size.width, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);

for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
if (_inputMode == KKPasscodeInputModeDefault) {
for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
}

[UIView beginAnimations:@"" context:nil];
[UIView setAnimationDuration:0.25];
Expand Down Expand Up @@ -469,8 +512,10 @@ - (void)vaildatePasscode:(UITextField*)textField
} else if ([textField isEqual:_setPasscodeTextField]) {
if ([passcode isEqualToString:_setPasscodeTextField.text]) {
_setPasscodeTextField.text = @"";
for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
if (_inputMode == KKPasscodeInputModeDefault) {
for (int i = 0; i < kPasscodeBoxesCount; i++) {
[[[_boxes objectAtIndex:_currentPanel] objectAtIndex:i] setImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
}
}
_passcodeConfirmationWarningLabel.text = KKPasscodeLockLocalizedString(@"Enter a different passcode. You cannot re-use the same passcode.", @"");
_passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 132.0, self.view.bounds.size.width, 60.0);
Expand Down Expand Up @@ -641,19 +686,30 @@ - (NSArray*)boxes
{
NSMutableArray* squareViews = [NSMutableArray array];

CGFloat squareX = self.isSmallLandscape ? 60.0f : 0.0f;

CGFloat width = self.isSmallLandscape ? kPasscodeBoxWidth * 0.6f : kPasscodeBoxWidth;
CGFloat height = self.isSmallLandscape ? kPasscodeBoxHeight * 0.6f : kPasscodeBoxHeight;

for (int i = 0; i < kPasscodeBoxesCount; i++) {
UIImageView *square = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
square.frame = CGRectMake(squareX, self.isSmallLandscape ? 32.0f : 74.0, width, height);
[squareViews addObject:square];
squareX += self.isSmallLandscape ? 42.0f : 71.0;
}
if (_inputMode == KKPasscodeInputModeDefault) {
CGFloat squareX = self.isSmallLandscape ? 60.0f : 0.0f;

CGFloat width = self.isSmallLandscape ? kPasscodeBoxWidth * 0.6f : kPasscodeBoxWidth;
CGFloat height = self.isSmallLandscape ? kPasscodeBoxHeight * 0.6f : kPasscodeBoxHeight;

for (int i = 0; i < kPasscodeBoxesCount; i++) {
UIImageView *square = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"]];
square.frame = CGRectMake(squareX, self.isSmallLandscape ? 32.0f : 74.0, width, height);
[squareViews addObject:square];
squareX += self.isSmallLandscape ? 42.0f : 71.0;
}
}
return [NSArray arrayWithArray:squareViews];
}
#define kPasscodeTextFieldHeight 44
- (CGRect)textFieldFrame
{
CGFloat x = self.isSmallLandscape ? 60.0f : 0.0f;
CGFloat y = self.isSmallLandscape ? 32.0f : 74.0f;
CGFloat w = (self.isSmallLandscape ? floorf(kPasscodeBoxWidth*4*0.6) : (kPasscodeBoxWidth*4)) + 30.0f;
CGFloat h = self.isSmallLandscape ? kPasscodeTextFieldHeight * 0.6f : kPasscodeTextFieldHeight;
return CGRectMake(x, y, w, h);
}

#pragma mark -
#pragma mark UITableViewDataSource methods
Expand All @@ -680,14 +736,16 @@ - (UITableViewCell*)tableView:(UITableView*)aTableView cellForRowAtIndexPath:(NS
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}

/*
if ([aTableView isEqual:_enterPasscodeTableView]) {
cell.accessoryView = _enterPasscodeTextField;
} else if ([aTableView isEqual:_setPasscodeTableView]) {
cell.accessoryView = _setPasscodeTextField;
} else if ([aTableView isEqual:_confirmPasscodeTableView]) {
cell.accessoryView = _confirmPasscodeTextField;
}

*/

return cell;
}

Expand All @@ -705,25 +763,23 @@ - (BOOL)textFieldShouldReturn:(UITextField*)textField
return NO;
}





- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string];
textField.text = result;

for (int i = 0; i < kPasscodeBoxesCount; i++) {
UIImageView *square = [[_boxes objectAtIndex:_currentPanel] objectAtIndex:i];
if (i < [result length]) {
square.image = [UIImage imageNamed:@"KKPasscodeLock.bundle/box_filled.png"];
} else {
square.image = [UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"];
if (_inputMode == KKPasscodeInputModeDefault) {
for (int i = 0; i < kPasscodeBoxesCount; i++) {
UIImageView *square = [[_boxes objectAtIndex:_currentPanel] objectAtIndex:i];
if (i < [result length]) {
square.image = [UIImage imageNamed:@"KKPasscodeLock.bundle/box_filled.png"];
} else {
square.image = [UIImage imageNamed:@"KKPasscodeLock.bundle/box_empty.png"];
}
}
}

if ([result length] == kPasscodeBoxesCount) {
if (_inputMode == KKPasscodeInputModeDefault && [result length] == kPasscodeBoxesCount) {
[self vaildatePasscode:textField];
}

Expand Down