2929
3030#import " JHVerificationCodeView.h"
3131
32+ #define kFlickerAnimation @" kFlickerAnimation"
33+
3234@implementation JHVCConfig
3335
3436- (instancetype )init {
3537 if (self = [super init ]) {
3638 _inputBoxBorderWidth = 1.0 /[UIScreen mainScreen ].scale ;
3739 _inputBoxSpacing = 5 ;
3840 _inputBoxColor = [UIColor lightGrayColor ];
41+ _tintColor = [UIColor blueColor ];
42+ _showFlickerAnimation = YES ;
43+ _underLineColor = [UIColor lightGrayColor ];
3944 }
4045 return self;
4146}
@@ -49,6 +54,10 @@ @interface JHVerificationCodeView()
4954
5055@implementation JHVerificationCodeView
5156
57+ - (void )dealloc {
58+ [[NSNotificationCenter defaultCenter ] removeObserver: self ];
59+ }
60+
5261- (instancetype )initWithFrame : (CGRect)frame config : (JHVCConfig *)config {
5362 if (self = [super initWithFrame: frame]) {
5463 _config = config;
@@ -97,6 +106,19 @@ - (void)jhSetupViews:(CGRect)frame
97106 }
98107 inputBoxHeight = _config.inputBoxHeight ;
99108
109+ if (_config.showUnderLine ) {
110+ if (_config.underLineSize .width <= 0 ) {
111+ CGSize size = _config.underLineSize ;
112+ size.width = inputBoxWidth;
113+ _config.underLineSize = size;
114+ }
115+ if (_config.underLineSize .height <= 0 ) {
116+ CGSize size = _config.underLineSize ;
117+ size.height = 1 ;
118+ _config.underLineSize = size;
119+ }
120+ }
121+
100122 for (int i = 0 ; i < _config.inputBoxNumber ; ++i) {
101123 UITextField *textField = [[UITextField alloc ] init ];
102124 textField.frame = CGRectMake (_config.leftMargin +(inputBoxWidth+inputBoxSpacing)*i, (CGRectGetHeight (frame)-inputBoxHeight)*0.5 , inputBoxWidth, inputBoxHeight);
@@ -111,7 +133,20 @@ - (void)jhSetupViews:(CGRect)frame
111133 textField.layer .borderColor = _config.inputBoxColor .CGColor ;
112134 }
113135 if (_config.tintColor ) {
114- textField.tintColor = _config.tintColor ;
136+ if (inputBoxWidth > 2 && inputBoxHeight > 8 ) {
137+ CGFloat w = 2 , y = 4 , x = (inputBoxWidth-w)/2 , h = inputBoxHeight-2 *y;
138+ [textField.layer addSublayer: ({
139+ UIBezierPath *path = [UIBezierPath bezierPathWithRect: CGRectMake (x,y,w,h)];
140+ CAShapeLayer *layer = [CAShapeLayer layer ];
141+ layer.path = path.CGPath ;
142+ layer.fillColor = _config.tintColor .CGColor ;
143+ [layer addAnimation: [self xx_alphaAnimation ] forKey: kFlickerAnimation ];
144+ if (i != 0 ) {
145+ layer.hidden = YES ;
146+ }
147+ layer;
148+ })];
149+ }
115150 }
116151 if (_config.secureTextEntry ) {
117152 textField.secureTextEntry = _config.secureTextEntry ;
@@ -122,6 +157,17 @@ - (void)jhSetupViews:(CGRect)frame
122157 if (_config.textColor ) {
123158 textField.textColor = _config.textColor ;
124159 }
160+ if (_config.showUnderLine ) {
161+ CGFloat x = (inputBoxWidth-_config.underLineSize .width )/2.0 ;
162+ CGFloat y = (inputBoxHeight-_config.underLineSize .height );
163+ CGRect frame = CGRectMake (x, y, _config.underLineSize .width , _config.underLineSize .height );
164+
165+ UIView *underLine = [[UIView alloc ] init ];
166+ underLine.frame = frame;
167+ underLine.backgroundColor = _config.underLineColor ;
168+ [textField addSubview: underLine];
169+
170+ }
125171
126172 textField.tag = i;
127173 textField.userInteractionEnabled = NO ;
@@ -136,7 +182,9 @@ - (void)jhSetupViews:(CGRect)frame
136182 _textView.frame = CGRectMake (0 , CGRectGetHeight (frame), 0 , 0 );
137183 _textView.secureTextEntry = YES ;
138184 [self addSubview: _textView];
139- [[NSNotificationCenter defaultCenter ] addObserver: self selector: @selector (textChange: ) name: UITextViewTextDidChangeNotification object: _textView];
185+
186+ [[NSNotificationCenter defaultCenter ] addObserver: self selector: @selector (xx_textChange: ) name: UITextViewTextDidChangeNotification object: _textView];
187+ [[NSNotificationCenter defaultCenter ] addObserver: self selector: @selector (xx_didBecomeActive ) name: UIApplicationDidBecomeActiveNotification object: nil ];
140188
141189 if (_config.autoShowKeyboard ) {
142190 dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t )(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^{
@@ -145,23 +193,58 @@ - (void)jhSetupViews:(CGRect)frame
145193 }
146194}
147195
196+ - (CABasicAnimation *)xx_alphaAnimation {
197+ CABasicAnimation *alpha = [CABasicAnimation animationWithKeyPath: @" opacity" ];
198+ alpha.fromValue = @(1.0 );
199+ alpha.toValue = @(0.0 );
200+ alpha.duration = 1.0 ;
201+ alpha.repeatCount = CGFLOAT_MAX;
202+ alpha.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut ];
203+ return alpha;
204+ }
205+
148206- (void )xx_tap {
149207 [_textView becomeFirstResponder ];
150208}
151209
152- - (void )dealloc {
153- [[NSNotificationCenter defaultCenter ] removeObserver: self ];
210+ - (void )xx_didBecomeActive {
211+ // restart Flicker Animation
212+ if (_config.showFlickerAnimation && _textView.text .length < self.subviews .count ) {
213+ UITextField *textField = self.subviews [_textView.text.length];
214+ CALayer *layer = textField.layer .sublayers [0 ];
215+ [layer removeAnimationForKey: kFlickerAnimation ];
216+ [layer addAnimation: [self xx_alphaAnimation ] forKey: kFlickerAnimation ];
217+ }
154218}
155219
156- - (void )textChange : (NSNotification *)noti
220+ - (void )xx_textChange : (NSNotification *)noti
157221{
222+ NSLog (@" %@ " ,noti.object );
158223 if (_textView != noti.object ) {
159224 return ;
160225 }
161226
162- // 去空格
227+ NSInteger count = _config.inputBoxNumber ;
228+
229+ // set default
230+ for (int i = 0 ; i < count; ++i) {
231+ UITextField *textField = self.subviews [i];
232+ textField.text = @" " ;
233+
234+ if (_config.inputBoxColor ) {
235+ textField.layer .borderColor = _config.inputBoxColor .CGColor ;
236+ }
237+ if (_config.showFlickerAnimation ) {
238+ CALayer *layer = textField.layer .sublayers [0 ];
239+ layer.hidden = YES ;
240+ [layer removeAnimationForKey: kFlickerAnimation ];
241+ }
242+ }
243+
244+ // trim space
163245 NSString *text = [_textView.text stringByReplacingOccurrencesOfString: @" " withString: @" " ];
164- // 保留数字和字母
246+ // number & alphabet
247+
165248 NSMutableString *mstr = @" " .mutableCopy ;
166249 for (int i = 0 ; i < text.length ; ++i) {
167250 unichar c = [text characterAtIndex: i];
@@ -184,22 +267,14 @@ - (void)textChange:(NSNotification *)noti
184267 }
185268
186269 text = mstr;
187- if (text.length > 6 ) {
188- text = [text substringToIndex: 6 ];
270+ if (text.length > count ) {
271+ text = [text substringToIndex: count ];
189272 }
190273 _textView.text = text;
191274
192275 NSLog (@" %@ " ,text);
193276
194- for (int i = 0 ; i < 6 ; ++i) {
195- UITextField *textField = self.subviews [i];
196- textField.text = @" " ;
197-
198- if (_config.inputBoxColor ) {
199- textField.layer .borderColor = _config.inputBoxColor .CGColor ;
200- }
201- }
202-
277+ // set value
203278 for (int i = 0 ; i < text.length ; ++i) {
204279 unichar c = [text characterAtIndex: i];
205280 UITextField *textField = self.subviews [i];
@@ -210,7 +285,15 @@ - (void)textChange:(NSNotification *)noti
210285 }
211286 }
212287
213- if (text.length == 6 ) {
288+ // Flicker Animation
289+ if (_config.showFlickerAnimation && text.length < self.subviews .count ) {
290+ UITextField *textField = self.subviews [text.length];
291+ CALayer *layer = textField.layer .sublayers [0 ];
292+ layer.hidden = NO ;
293+ [layer addAnimation: [self xx_alphaAnimation ] forKey: kFlickerAnimation ];
294+ }
295+
296+ if (text.length == count) {
214297 [self xx_finish ];
215298 }
216299}
0 commit comments