0

NSTextField、NSTextView などのすべての UIControls を検証するための一般的なメソッドを作成したいと考えています。必須フィールドが空の場合、最初のコントロールがフォーカスされた/ファーストレスポンダーとして統合された 1 つのアラートが表示されます。

私はこのようなものを実装しました:

-(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など)を取得しているため、さらに一般的なものにしたいと思います。

また、これに関する他の提案も大歓迎です。

4

2 に答える 2

0

ユーザーに表示される文字列の内容に基づいてロジック (エラーがあったかどうかを判断) をしています。すべきではありません。代わりに、変更できないキー ( ) に基づいてロジックを作成しますcontrol。これと併せてNSLocalizedString、再利用のためにコードを将来証明するために使用する必要があります。

イントロスペクションのために、これらのメソッドをユーティリティ クラスに入れ、そのクラスにもいくつかのカテゴリを追加することを検討します。カテゴリは、常に同じ名前のメソッドを呼び出すことによってNSControlそれらを取得できるようにすることを目的として、各サブクラスに単一のメソッドを追加します。stringValueカテゴリはNSTextField必要ないからです。NSTextViewカテゴリは次のようになります。

@implementation NSTextView (MyStringValue)

- (NSString *)stringValue
{
    return [self string];
}

@end

クラスがstringValueセレクターに応答することをコードで検証する必要がありますが、そうでない場合は検証できません。

于 2013-05-11T07:40:42.013 に答える
0

コントロールをView Controllerのプロパティにバインドすると役立つ場合があります。

@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 (フォーマッタの仕事) の健全性をチェックするのではなく、既に変換/フォーマットされた値をチェックします。

于 2013-05-11T11:42:44.573 に答える