4

値トランスフォーマーを使用したバインディングによって設定されたポップアップ ボタンで表示されるものが、本来あるべき方法であるかどうかはわかりません。値トランスフォーマーとテーブル ビュー) は、transformedValue: メソッドの "value" パラメーターが、配列内の個々の文字列ではなく、配列コントローラーにバインドされた配列全体であることです。テーブルビューでこれを行った場合、トランスフォーマーはテーブルに表示された行ごとに1回呼び出され、「値」パラメーターは、コンテンツ配列として機能する配列全体ではなく、その行と列にバインドされているオブジェクトですアレイコントローラー用。

これをテストするための非常に単純なアプリがあります。アプリのデリゲートには次のものがあります。

+(void)initialize {
    RDTransformer *transformer = [[RDTransformer alloc] init];
    [NSValueTransformer setValueTransformer:transformer forName:@"testTransformer"];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.theData = @[@{@"name":@"William", @"age":@"24"},@{@"name":@"Thomas", @"age":@"23"},@{@"name":@"Alexander", @"age":@"64"},@{@"name":@"James", @"age":@"47"}];
}

RDTransformer クラスには次のものがあります。

+ (Class)transformedValueClass {
    return [NSString class];
}


+(BOOL)allowsReverseTransformation {
    return NO;
}

-(id)transformedValue:(id)value {
    NSLog(@"%@",value);
    return value;
}

IB では、ウィンドウに NSPopupButton を追加し、オブジェクト リストに配列コントローラーを追加しました。コントローラーのコンテンツ配列は App Delegate.theData にバインドされ、ポップアップ ボタンのコンテンツ値は値トランスフォーマー testTransformer を使用して Array Controller.arrangedObjects.name にバインドされます。

プログラムを実行すると、TransformedValue: メソッドからのログは次のようになります。

2012-09-19 20:31:39.975 PopupBindingWithTransformer[793:303] (
)
2012-09-19 20:31:40.019 PopupBindingWithTransformer[793:303] (
    William,
    Thomas,
    Alexander,
    James
)

これは、私が SO で見ることができる他の人の経験ではないようです。バインディングまたは値トランスフォーマーのいずれかで間違っていることはありますか?

4

1 に答える 1

7

残念ながら、これがNSPopUpButtonの動作方法です。問題はその制御に限定されません。NSArrayController.contentArrayを別のNSArrayControllers.arrangedObject.somePropertyにバインドしようとすると、同じ問題が発生します。これは、すべてのバリュートランスフォーマーで使用する簡単な回避策であり、テーブルとポップアップの両方で機能します。

次の方法でバリュートランスフォーマーを変更できます。

-(id)transformedArrayValue:(NSArray*)array
{
    NSMutableArray *result = [NSMutableArray array];
    for (id value in array)
        [result addObject:[self transformedValue:value]];

    return result;
}

-(id)transformedValue:(id)value
{
    if ([value isKindOfClass:[NSArray class]])
        return [self transformedArrayValue:value];

    // Do your normal-case transform...
    return [value lowercaseString];
}

完璧ではありませんが、簡単に複製できます。私は実際にtransformedArrayValue:クラスカテゴリに入れているので、どこにでもコピーする必要はありません。

于 2012-09-24T19:47:53.197 に答える