123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- //
- // BKPasscodeField.m
- // BKPasscodeViewDemo
- //
- // Created by Byungkook Jang on 2014. 4. 20..
- // Copyright (c) 2014년 Byungkook Jang. All rights reserved.
- //
- #import "BKPasscodeField.h"
- @interface BKPasscodeField ()
- @property (strong, nonatomic) NSMutableString *mutablePasscode;
- @property (strong, nonatomic) NSRegularExpression *nonDigitRegularExpression;
- @end
- @implementation BKPasscodeField
- - (id)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- [self _initialize];
- }
- return self;
- }
- - (id)initWithCoder:(NSCoder *)aDecoder
- {
- self = [super initWithCoder:aDecoder];
- if (self) {
- [self _initialize];
- }
- return self;
- }
- - (id)init
- {
- self = [super init];
- if (self) {
- [self _initialize];
- }
- return self;
- }
- - (void)_initialize
- {
- _maximumLength = 4;
- _dotSize = CGSizeMake(18.0f, 19.0f);
- _dotSpacing = 25.0f;
- _lineHeight = 3.0f;
- _dotColor = [UIColor blackColor];
-
- self.backgroundColor = [UIColor clearColor];
-
- _mutablePasscode = [[NSMutableString alloc] initWithCapacity:4];
-
- [self addTarget:self action:@selector(didTouchUpInside:) forControlEvents:UIControlEventTouchUpInside];
- }
- - (NSRegularExpression *)nonDigitRegularExpression
- {
- if (nil == _nonDigitRegularExpression) {
- _nonDigitRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"[^0-9]+" options:0 error:nil];
- }
- return _nonDigitRegularExpression;
- }
- - (NSString *)passcode
- {
- return self.mutablePasscode;
- }
- - (void)setPasscode:(NSString *)passcode
- {
- if (passcode) {
- if (passcode.length > self.maximumLength) {
- passcode = [passcode substringWithRange:NSMakeRange(0, self.maximumLength)];
- }
- self.mutablePasscode = [NSMutableString stringWithString:passcode];
- } else {
- self.mutablePasscode = [NSMutableString string];
- }
-
- [self setNeedsDisplay];
- }
- #pragma mark - UIKeyInput
- - (BOOL)hasText
- {
- return (self.mutablePasscode.length > 0);
- }
- - (void)insertText:(NSString *)text
- {
- if (self.enabled == NO) {
- return;
- }
-
- if (self.keyboardType == UIKeyboardTypeNumberPad) {
- text = [self.nonDigitRegularExpression stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, text.length) withTemplate:@""];
- }
-
- if (text.length == 0) {
- return;
- }
-
- NSInteger newLength = self.mutablePasscode.length + text.length;
- if (newLength > self.maximumLength) {
- return;
- }
-
- if ([self.delegate respondsToSelector:@selector(passcodeField:shouldInsertText:)]) {
- if (NO == [self.delegate passcodeField:self shouldInsertText:text]) {
- return;
- }
- }
-
- [self.mutablePasscode appendString:text];
- [self setNeedsDisplay];
-
- [self sendActionsForControlEvents:UIControlEventEditingChanged];
- }
- - (void)deleteBackward
- {
- if (self.enabled == NO) {
- return;
- }
-
- if ([self.delegate respondsToSelector:@selector(passcodeFieldShouldDeleteBackward:)]) {
- if (NO == [self.delegate passcodeFieldShouldDeleteBackward:self]) {
- return;
- }
- }
-
- if (self.mutablePasscode.length == 0) {
- return;
- }
-
- [self.mutablePasscode deleteCharactersInRange:NSMakeRange(self.mutablePasscode.length - 1, 1)];
-
- [self setNeedsDisplay];
-
- [self sendActionsForControlEvents:UIControlEventEditingChanged];
- }
- - (UITextAutocapitalizationType)autocapitalizationType
- {
- return UITextAutocapitalizationTypeNone;
- }
- - (UITextAutocorrectionType)autocorrectionType
- {
- return UITextAutocorrectionTypeNo;
- }
- - (UITextSpellCheckingType)spellCheckingType
- {
- return UITextSpellCheckingTypeNo;
- }
- - (BOOL)enablesReturnKeyAutomatically
- {
- return YES;
- }
- - (UIKeyboardAppearance)keyboardAppearance
- {
- return UIKeyboardAppearanceDefault;
- }
- - (UIReturnKeyType)returnKeyType
- {
- return UIReturnKeyDone;
- }
- - (BOOL)isSecureTextEntry
- {
- return YES;
- }
- #pragma mark - UIView
- - (CGSize)contentSize
- {
- return CGSizeMake(self.maximumLength * _dotSize.width + (self.maximumLength - 1) * _dotSpacing,
- _dotSize.height);
- }
- - (void)setFrame:(CGRect)frame
- {
- [super setFrame:frame];
- [self setNeedsDisplay];
- }
- - (void)drawRect:(CGRect)rect
- {
- CGSize contentSize = [self contentSize];
-
- CGPoint origin = CGPointMake(floorf((self.frame.size.width - contentSize.width) * 0.5f),
- floorf((self.frame.size.height - contentSize.height) * 0.5f));
-
- if ([self.imageSource respondsToSelector:@selector(passcodeField:dotImageAtIndex:filled:)]) {
-
- for (NSUInteger i = 0; i < self.maximumLength; i++) {
-
- UIImage *image = nil;
-
- if (i < self.mutablePasscode.length) {
- // draw filled image
- image = [self.imageSource passcodeField:self dotImageAtIndex:i filled:YES];
- } else {
- // draw blank image
- image = [self.imageSource passcodeField:self dotImageAtIndex:i filled:NO];
- }
-
- if (image) {
- CGRect imageFrame = CGRectMake(origin.x, origin.y, self.dotSize.width, self.dotSize.height);
- [image drawInRect:imageFrame];
- }
-
- origin.x += (self.dotSize.width + self.dotSpacing);
- }
-
- } else {
-
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGContextSetFillColorWithColor(context, self.dotColor.CGColor);
-
- for (NSUInteger i = 0; i < self.maximumLength; i++) {
-
- if (i < self.mutablePasscode.length) {
- // draw circle
- CGRect circleFrame = CGRectMake(origin.x, origin.y, self.dotSize.width, self.dotSize.height);
- CGContextFillEllipseInRect(context, circleFrame);
- } else {
- // draw line
- CGRect lineFrame = CGRectMake(origin.x, origin.y + floorf((self.dotSize.height - self.lineHeight) * 0.5f),
- self.dotSize.width, self.lineHeight);
- CGContextFillRect(context, lineFrame);
- }
-
- origin.x += (self.dotSize.width + self.dotSpacing);
- }
- }
- }
- - (CGSize)sizeThatFits:(CGSize)size
- {
- return [self contentSize];
- }
- #pragma mark - UIResponder
- - (BOOL)canBecomeFirstResponder
- {
- return YES;
- }
- #pragma mark - Actions
- - (void)didTouchUpInside:(id)sender
- {
- [self becomeFirstResponder];
- }
- @end
|