整體的目錄結(jié)構(gòu)
屏幕快照 2017-04-06 上午8.45.33.png
分批次描述:
屏幕快照 2017-04-06 上午8.44.44.png
cell 文件夾
cell文件夾
沒有必要一一講述,這里就是不同元素,每個元素其實都是UITableViewCell,但是為了統(tǒng)一封裝都繼承了XLFormBaseCell,最后在統(tǒng)一繼承UITableViewCell
Controllers 文件夾
Controllers 文件夾
Descriptors(描述) 文件夾
Descriptors(描述) 文件夾
Helpers(分類) 文件夾
Helpers(分類) 文件夾
Validation(限制) 文件夾
Validation(限制)文件夾
里面可以集成對各個輸入的一些限制判斷销钝,在其中可以通過正則表達式來限制厕吉。
XLFormRegexValidator類為解析正正則表達式酱固,判斷出是否符合輸入限制,其核心代碼
-(XLFormValidationStatus *)isValid: (XLFormRowDescriptor *)row {
if (row != nil && row.value != nil) {
// we only validate if there is a value
// assumption: required validation is already triggered
// if this field is optional, we only validate if there is a value
id value = row.value;
if ([value isKindOfClass:[NSNumber class]]){
value = [value stringValue];
}
if ([value isKindOfClass:[NSString class]] && [value length] > 0) {
//通過謂詞這種高級特性判斷輸入內(nèi)容是否符合標準
BOOL isValid = [[NSPredicate predicateWithFormat:@"SELF MATCHES %@", self.regex] evaluateWithObject:[value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
//將結(jié)果建立一個模型
return [XLFormValidationStatus formValidationStatusWithMsg:self.msg status:isValid rowDescriptor:row];
}
}
return nil;
};
XLFormValidationStatus 其實就是一個是否符合標準的模型头朱。
XLFormValidator判斷輸入是否符合標準的集合运悲,所有的規(guī)則都在其中編寫,可以做到很好的復(fù)用项钮。
XLFormValidatorProtocol所有的限制規(guī)則都要遵守該協(xié)議班眯。
下面簡述一個限制的判斷過程,已判斷輸入是否為郵箱為例:
首先在創(chuàng)建界面界面階段要先加上對該條的判斷規(guī)則
[row addValidator:[XLFormValidator emailValidator]];
然后再** XLFormValidator**中實現(xiàn)該方法
+(XLFormValidator *)emailValidator
{
return [XLFormRegexValidator formRegexValidatorWithMsg:NSLocalizedString(@"郵箱地址輸入有誤", nil) regex:@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"];
}
運行時該條限定條件會添加到該元素的validators 數(shù)組中烁巫,也就是說署隘,同一個元素可以存在多條限制
-(void)addValidator:(id<XLFormValidatorProtocol>)validator
{
if (validator == nil || ![validator conformsToProtocol:@protocol(XLFormValidatorProtocol)])
return;
if(![self.validators containsObject:validator]) {
[self.validators addObject:validator];
}
}
在提交表單的時候,可以進行檢查
NSArray * validationErrors = [self formValidationErrors];
if (validationErrors.count > 0){
[self showFormValidationError:[validationErrors firstObject]];
return;
}
跳來跳去會跳到-(NSArray *)localValidationErrors:(XLFormViewController *)formViewController
函數(shù)亚隙,內(nèi)部會把所有元素挨個遍歷一遍尋找所有的磁餐,把所有不合格的輸入都挑出來其中遍歷元素的是[row doValidation]
方法
- (BOOL)valueIsEmpty
{
return self.value == nil || [self.value isKindOfClass:[NSNull class]] || ([self.value respondsToSelector:@selector(length)] && [self.value length]==0) ||
([self.value respondsToSelector:@selector(count)] && [self.value count]==0);
}
-(XLFormValidationStatus *)doValidation
{
XLFormValidationStatus *valStatus = nil;
if (self.required) { //判斷輸入是否為必須輸入,如果為非必輸則跳過
// do required validation here
if ([self valueIsEmpty]) {//判斷元素是否為空
valStatus = [XLFormValidationStatus formValidationStatusWithMsg:@"" status:NO rowDescriptor:self];
NSString *msg = nil;
if (self.requireMsg != nil) {
msg = self.requireMsg;
} else {
// default message for required msg
msg = NSLocalizedString(@"%@ can't be empty", nil);
}
if (self.title != nil) {
valStatus.msg = [NSString stringWithFormat:msg, self.title];
} else {
valStatus.msg = [NSString stringWithFormat:msg, self.tag];
}
return valStatus;
}
}
// custom validator 遍歷限制規(guī)則
for(id<XLFormValidatorProtocol> v in self.validators) {
if ([v conformsToProtocol:@protocol(XLFormValidatorProtocol)]) {
XLFormValidationStatus *vStatus = [v isValid:self];//實現(xiàn)協(xié)議的方法 生成一個是否成功的模型
// fail validation
if (vStatus != nil && !vStatus.isValid) {
return vStatus;
}
valStatus = vStatus;
} else {
valStatus = nil;
}
}
return valStatus;
}
根據(jù)這一些列操作就可以判斷出是否輸入是否符合限制
/**
遍歷所有元素返回不符合輸入規(guī)則的元素阿弃,并且返回相應(yīng)的錯誤信息
@param formViewController formViewController description
@return return value description
*/
-(NSArray *)localValidationErrors:(XLFormViewController *)formViewController {
NSMutableArray * result = [NSMutableArray array];
for (XLFormSectionDescriptor * section in self.formSections) {
for (XLFormRowDescriptor * row in section.formRows) {
XLFormValidationStatus* status = [row doValidation];
if (status != nil && (![status isValid])) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: status.msg,
XLValidationStatusErrorKey: status };
NSError * error = [[NSError alloc] initWithDomain:XLFormErrorDomain code:XLFormErrorCodeGen userInfo:userInfo];
if (error){
[result addObject:error];
}
}
}
}
return result;
}