在iOS开发过程中,UITextField肯定是各个开发者最常接触到的控件之一,而UIKit库对于UITextfield的封装也似乎满足不了需求人员和产品经理的要求,在被虐过数次之后,我终于下定决心要重写对于UITextField的封装和工具类,于是乎,有了接下来的几段代码,其中用到了模板方法模式和策略模式。
首先描述一下需求:
1、需要让UITextField在输入过程中能够动态的去判断输入是否满足要求;
2、需要让UITextField在键盘弹起过程中,给键盘加上一些外设,包括顶部UIToolbar上的的完成按钮和一个UIPickerView控件;
于是乎,我对应做出了调整:
1、继承了UITextField,在
- (void)textViewDidChange:(NSNotification *)notification
函数中用来控制用户每次输入的验证过程。2、在
- (void)willMoveToSuperview:(UIView *)newSuperview
中加上一些外部控制的控件。主要代码贴出来如下
PBFUITextFieldVerify.h
//
// PBFUITextFieldVerify.h
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
//
// UITextField控制文字类型
#import <UIKit/UIKit.h>
//增加组件
@protocol PBFUITextFieldVerifyAdditionDelegate
- (void)additionComponent:(UITextField*)textField;
@end
//验证策略
@protocol PBFUITextFieldVerifyStrategyDelegate
- (BOOL)isValidate:(NSString *)strText;
@end
@interface PBFUITextFieldVerify : UITextField
- (instancetype)initWithStrategy;
- (instancetype)initWithStrategyFrame:(CGRect)rect;
- (void)addAddition:(id<PBFUITextFieldVerifyAdditionDelegate>)addition;
- (void)addStrategy:(id<PBFUITextFieldVerifyStrategyDelegate>)strategyItem;
@end
PBFUITextFieldVerify.h
//
// PBFUITextFieldVerify.m
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import "PBFUITextFieldVerify.h"
@interface PBFUITextFieldVerify()
//策略
@property (nonatomic,strong)NSMutableArray *arrStrategys;
//组件
@property (nonatomic,strong)NSMutableArray *arrComponents;
@end
@implementation PBFUITextFieldVerify
- (instancetype)initWithStrategy{
self = [super init];
// self.delegate = self;
return self;
}
- (instancetype)initWithStrategyFrame:(CGRect)rect{
self = [super initWithFrame:rect];
// self.delegate = self;
[self addTarget:self action:@selector(textViewDidChange:) forControlEvents:UIControlEventEditingChanged];
return self;
}
- (instancetype)init{
return nil;
}
- (instancetype)initWithFrame:(CGRect)frame{
return nil;
}
- (void)addStrategy:(id<PBFUITextFieldVerifyStrategyDelegate>)strategyItem{
[self.arrStrategys addObject:strategyItem];
}
- (void)addAddition:(id<PBFUITextFieldVerifyAdditionDelegate>)addition{
[self.arrComponents addObject:addition];
}
- (void)willMoveToSuperview:(UIView *)newSuperview{
for (id<PBFUITextFieldVerifyAdditionDelegate> delegateAddition in self.arrComponents) {
[delegateAddition additionComponent:self];
}
}
- (BOOL)isAvaliable:(NSString *)strText{
for (id<PBFUITextFieldVerifyStrategyDelegate> delegateStrategy in self.arrStrategys) {
if (![delegateStrategy isValidate:strText]) {
return FALSE;
}
}
return TRUE;
}
- (void)textViewDidChange:(NSNotification *)notification{
if (![self isAvaliable:self.text] && [self.text length] > 0) {
self.text = [self.text substringToIndex:[self.text length]-1];
}
}
#pragma mark - getter and setter
- (NSMutableArray*)arrStrategys{
if(!_arrStrategys){
_arrStrategys = [[NSMutableArray alloc] init];
}
return _arrStrategys;
}
- (NSMutableArray*)arrComponents{
if(!_arrComponents){
_arrComponents = [[NSMutableArray alloc] init];
}
return _arrComponents;
}
@end
策略:
1、定长
PBFUITextFieldStratageMaxLength.h
//
// PBFUITextFieldStratageMaxLength.h
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "PBFUITextFieldVerify.h"
@interface PBFUITextFieldStratageMaxLength : NSObject<PBFUITextFieldVerifyStrategyDelegate>
- (instancetype)initWithMaxKLength:(long)lMaxLength;
@end
PBFUITextFieldStratageMaxLength.m
//
// PBFUITextFieldStratageMaxLength.m
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import "PBFUITextFieldStratageMaxLength.h"
@interface PBFUITextFieldStratageMaxLength()
@property (nonatomic,assign)long lMaxLength;
@end
@implementation PBFUITextFieldStratageMaxLength
- (instancetype)initWithMaxKLength:(long)lMaxLength{
self = [super init];
self.lMaxLength = lMaxLength;
return self;
}
- (BOOL)isValidate:(NSString *)strText{
if ([strText length] <= self.lMaxLength) {
return TRUE;
}
else{
return FALSE;
}
}
@end
2、正则表达式
PBFUITextFieldStratageRegex.h
//
// PBFUITextFieldStratageRegex.h
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "PBFUITextFieldVerify.h"
@interface PBFUITextFieldStratageRegex : NSObject<PBFUITextFieldVerifyStrategyDelegate>
- (instancetype)initWithRgex:(NSString*)strRegex;
- (BOOL)isValidate:(NSString *)strText;
@end
PBFUITextFieldStratageRegex.m
//
// PBFUITextFieldStratageRegex.m
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import "PBFUITextFieldStratageRegex.h"
#import "PBFNSStringTools.h"
@interface PBFUITextFieldStratageRegex()
@property (nonatomic,strong)NSString *strFormatString;
@end
@implementation PBFUITextFieldStratageRegex
- (instancetype)initWithRgex:(NSString*)strRegex{
self = [super init];
self.strFormatString = strRegex;
return self;
}
- (BOOL)isValidate:(NSString *)strText{
if ([PBFNSStringTools isRegularString:self.strFormatString strText:strText]) {
return TRUE;
}
else{
return FALSE;
}
}
@end
外设
1、增加完成按钮
PBFUITextFieldAdditionFinishedBtn.h
//
// PBFUITextFieldAdditionFinishedBtn.h
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "PBFUITextFieldVerify.h"
@interface PBFUITextFieldAdditionFinishedBtn : NSObject<PBFUITextFieldVerifyAdditionDelegate>
- (void)additionComponent:(UITextField*)textField;
@end
PBFUITextFieldAdditionFinishedBtn.m
//
// PBFUITextFieldAdditionFinishedBtn.m
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import "PBFUITextFieldAdditionFinishedBtn.h"
@interface PBFUITextFieldAdditionFinishedBtn()
@property(nonatomic,strong)UIToolbar *tbrTimeSel;
@property(nonatomic,strong)UITextField *textField;
@end
@implementation PBFUITextFieldAdditionFinishedBtn
- (void)additionComponent:(UITextField*)textField{
textField.inputAccessoryView = self.tbrTimeSel;
self.textField = textField;
}
#pragma mark - getter and setter
- (UIToolbar*)tbrTimeSel{
if (!_tbrTimeSel) {
_tbrTimeSel = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 40)];
//toolbarItem
UIBarButtonItem *itemSel = [[UIBarButtonItem alloc] initWithTitle:@"确定" style:UIBarButtonItemStyleDone target:self action:@selector(finfishedEdit:)];
itemSel.width = 50;
UIBarButtonItem *itemSelEmpty = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleDone target:nil action:nil];
itemSelEmpty.width = [UIScreen mainScreen].bounds.size.width - 90;
[_tbrTimeSel setItems:[NSArray arrayWithObjects:itemSelEmpty,itemSel, nil]];
}
return _tbrTimeSel;
}
- (void)finfishedEdit:(id)sender{
[self.textField resignFirstResponder];
}
@end
"PBFUITextFieldAdditionPickup.h
//
// PBFUITextFieldAdditionPickup.h
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import <Foundation/Foundation.h>
@class UITextField;
@interface PBFUITextFieldAdditionPickup : NSObject
- (instancetype)initWithSelRange:(NSArray*)range blockSel:(void(^)(long))blockSel;
- (void)additionComponent:(UITextField*)textField;
@end
"PBFUITextFieldAdditionPickup.m
//
// PBFUITextFieldAdditionPickup.m
// BoyingCaptial
//
// Created by BY-MAC01 on 15/12/22.
// Copyright © 2015年 BY-MAC01. All rights reserved.
//
#import "PBFUITextFieldAdditionPickup.h"
#import <UIKit/UIKit.h>
//调用完成后的回调函数
typedef void(^SelComplete)(long);
@interface PBFUITextFieldAdditionPickup()
@property(nonatomic,strong)UIPickerView *pkvTimePick;
@property(nonatomic,strong)SelComplete blockSel;
@property(nonatomic,strong)NSArray *ranges;
@property(nonatomic,strong)UITextField *textField;
@end
@implementation PBFUITextFieldAdditionPickup
- (instancetype)initWithSelRange:(NSArray*)range blockSel:(void(^)(long))blockSel{
self = [super init];
self.blockSel = blockSel;
self.ranges = range;
return self;
}
- (void)additionComponent:(UITextField*)textField{
textField.inputView = self.pkvTimePick;
self.textField = textField;
}
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [self.ranges count];
}
-(NSString*) pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [self.ranges objectAtIndex:row];
}
- (void)selTimeRange:(id)sender{
[self.textField resignFirstResponder];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
self.textField.text = [self.ranges objectAtIndex:row];
if (self.blockSel) {
self.blockSel(row);
}
}
#pragma mark - getter and setter
- (UIPickerView*)pkvTimePick{
if (!_pkvTimePick) {
//pkvPick
_pkvTimePick = [[UIPickerView alloc] init];
_pkvTimePick.delegate = self;
_pkvTimePick.dataSource = self;
}
return _pkvTimePick;
}
@end