我想编写一个泛型方法来验证所有UIControl,如NSTextField,NSTextView等。如果任何必填字段为空,则应显示一个统一的警报,第一个控件作为焦点/第一响应者。
我已经实现了这样的事情:
-(NSInteger)lengthAfterTrimmingSpaces:(NSString *)string{
return [[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length];
}
-(NSDictionary *)createWarningMessageForMandatoryFields:(NSArray *)uiObjects{
NSMutableString *warningString=[NSMutableString stringWithString:@"Enter "];
id firstInvalidatedControl=nil;
for (NSDictionary *object in uiObjects) {
NSString *key=[object allKeys][0];
id control=object[key];
if ([control isKindOfClass:[NSTextField class]]) {
if ([self lengthAfterTrimmingSpaces:[control stringValue]]==0){
[warningString appendString:key];
[warningString appendString:@", "];
if (firstInvalidatedControl==nil) {
firstInvalidatedControl=control;
}
}
}
else if ([control isKindOfClass:[NSTextView class]]) {
if ([self lengthAfterTrimmingSpaces:[control string]]==0){
[warningString appendString:key];
[warningString appendString:@", "];
if (firstInvalidatedControl==nil) {
firstInvalidatedControl=control;
}
}
}
}
if (firstInvalidatedControl==nil) {
return @{@"warningString":@"Success"};
}
else{
warningString =[[warningString substringToIndex:[warningString length] - 2]mutableCopy];
return @{@"warningString":warningString, @"control":firstInvalidatedControl};
}
}
-(BOOL)validateMandatoryFields{
NSMutableArray *uiObjects=[NSMutableArray array];
[uiObjects addObject:@{@"Segment Name":self.segmentName}];
[uiObjects addObject:@{@"Code":self.code}];
[uiObjects addObject:@{@"Desciption":self.description}];
NSDictionary *warningAndControl=[self createWarningMessageForMandatoryFields:uiObjects];
if ([warningAndControl[@"warningString"] isEqualToString:@"Success"]) {
return YES;
}
else{
[[self window] makeFirstResponder:warningAndControl[@"control"]];
NSRunAlertPanel(@"Warning", warningAndControl[@"warningString"], @"OK", nil, nil);
return NO;
}
}
- (IBAction)save:(id)sender {
NSLog(@"%d",[self validateMandatoryFields]);
}
现在我想让它更通用,因为我正在进行类内省,然后检索值(stringValue / string等)。
此外,对此的任何其他建议表示赞赏。
答案 0 :(得分:0)
您将基于逻辑(判断是否存在错误)对将要呈现给用户的字符串的内容。你不应该。相反,将逻辑基于键(control
),因为它们是不可变的。与此同时,您应该使用NSLocalizedString
来证明代码的重用。
对于内省,我会考虑将这些方法放入实用程序类中,并在该类中添加许多类别。类别将为每个NSControl
子类添加一个方法,目的是允许您通过始终调用具有相同名称的方法来获取stringValue
。对于NSTextField
,您不需要类别。对于NSTextView
,该类别将为:
@implementation NSTextView (MyStringValue)
- (NSString *)stringValue
{
return [self string];
}
@end
您的代码仍应验证该类是否响应stringValue
选择器,如果不响应则无法验证。
答案 1 :(得分:0)
绑定控件以查看控制器的属性可能会有所帮助。
@interface MyViewController
@property(nonatomic,copy) NSString *string;
@property(nonatomic,copy) NSDate *date;
@property(nonatomic,copy) NSNumber *number;
@end
现在,您将控制值绑定到文件所有者的string
/ date
/ number
属性。
@implementation MyViewController
- (void)testForm
{
for (NSString *key in @[@"string", @"date", @"number"]) {
id value = [self valueForKey:key];
if (value == nil || [value isEqual:@""] || [value isEqual:@(0.0)] || ...) {
// empty field
}
}
}
请注意,您在此处使用实际数据,即如果您有日期/数字字段,则不会检查它的stringValue(即格式化程序的作业)的完整性,而是检查已转换/格式化的值。