4

私は、比較的一般的なタスクだと思うことを実行しようと奮闘しています。をNSTableView介してその配列にバインドされているがありNSArrayControllerます。アレイコントローラのコンテンツは、モデルクラスのNSMutableArray1つ以上のインスタンスを含むに設定されています。NSObject方法がわからないのは、NSCellバインディングに適した方法でサブクラス内のモデルを公開することです。

説明のために、オブジェクトモデルは、名、名前、年齢、性別で構成される人物であると言います。したがって、モデルは次のようになります。

@interface PersonModel : NSObject {
    NSString * firstName;
    NSString * lastName;
    NSString * gender;
    int * age;
}

明らかに、クラスに適切なセッター、ゲッターinitなど。

私のコントローラークラスでは、、、および:を定義NSTableViewNSMutableArrayますNSArrayController

@interface ControllerClass : NSObject {
    IBOutlet NSTableView * myTableView;
    NSMutableArray * myPersonArray;
    IBOutlet NSArrayController * myPersonArrayController;
}

Interface Builderを使用すると、モデルを適切な列に簡単にバインドできます。

myPersonArray --> myPersonArrayController --> table column binding

これは正常に機能します。したがって、余分な列を削除し、NSArrayController(各行との間の関連付けを作成して維持する)にバインドされている1つの列を非表示のままNSArrayControllerにして、1つの非表示のNSTableView列と1つの非表示の列に移動します。NSCellサブクラスを作成し、適切な描画メソッドを配置してセルを作成します。私のawakeFromNib中で私はカスタムNSCellサブクラスを確立します:

MyCustomCell * aCustomCell = [[[MyCustomCell alloc] init] autorelease];
[[myTableView tableColumnWithIdentifier:@"customCellColumn"] 
     setDataCell:aCustomCell];

これも、描画の観点からは問題なく機能します。カスタムセルが列に表示され、アレイコントローラー内のすべての管理対象オブジェクトに対して繰り返されます。オブジェクトを追加したり、アレイコントローラからオブジェクトを削除したりすると、それに応じてテーブルが更新されます。

しかし...私は自分のオブジェクトが私のサブクラスPersonModel内から利用できるだろうという印象を受けました。NSCellしかし、私はそれに到達する方法がわかりません。セッターとゲッターを使用してそれぞれを設定したくないのは、配列コントローラーからデータを参照するのNSCellではなく、データを格納することでモデルの概念全体を壊しているためです。NSCell

そして、はい、私はカスタムを持っている必要があるNSCellので、複数の列を持つことはオプションではありません。ここからどこへ?

GoogleとStackOverflowの検索に加えて、私はAppleのドキュメントで必須のウォークスルーを実行しましたが、答えが見つからなかったようです。私は茂みの周りを打ち負かす多くの参照を見つけましたが、何も含まれていませんNSArrayController。コントローラーは、モデルエンティティの他の要素(マスター/詳細シナリオなど)にバインドするときに非常に簡単になります。Core Dataを使用しているときに、多くの参照(回答はありませんが)も見つかりましたが、CoreDataを使用していません。

当たり前のように、私は提供できるどんな援助にも非常に感謝しています!

4

3 に答える 3

3

ついにこれを理解した。やった男。だからここに私がする必要があったことです...

まず、モデルオブジェクトにモデルのキー値の配列を作成し、モデルNSDictionary内からそれらのキー値を返す必要がありました。

したがって、私のモデルには、次の2つの新しいメソッドがあります(上記の簡略化した例に基づく)。

+(NSArray *)personKeys
{
    static NSArray * personKeys = nil;
    if (personKeys == nil)
        personKeys = [[NSArray alloc] initWithObjects:@"firstName", @"lastName", @"gender", @"age", nil];

    return personKeys;
}

-(NSDictionary *)personDictionary
{
    return [self dictionaryWithValuesForKeys:[[self class] personKeys]];
}

value実装したら、テーブルの境界をに割り当てます

arrayController --> arrangeObjects --> personDictionary

最後のステップは、でオブジェクトを参照し、NSCell drawWithFrame必要に応じて次のように使用することです。

NSDictionary * thisCellObject = [self objectValue];

NSString * objectFirstName = [thisCellObject valueForkey:@"firstName"];
NSString * objectLastName = [thisCellObject valueForKey:@"lastName"];

そして、私が望んでいたように、モデルオブジェクトへの更新はすべてカスタムに反映されますNSCell

于 2010-04-20T23:25:33.823 に答える
1

辞書を必要としない別のアプローチがあります。ただし、データクラス内に-(id)copyWithZone:(NSZone *)zoneメソッドを実装する必要があります。例えば:

- (id)copyWithZone:(NSZone *)zone {
    Activity *copy = [[self class] allocWithZone: zone];
    copy.activityDate = self.activityDate;
    copy.sport = self.sport;
    copy.sportIcon = self.sportIcon;
    copy.laps = self.laps;
    return copy; }

IBでは、テーブル列の値をArrayController->arrangedObjectsにポイントします。

drawWithFrameメソッドは、objectValueから実際のオブジェクトを返すようになりました。

Activity *rowActivity = [self objectValue];

クラスを変更するには、copyWithZoneメソッドを更新してから、drawWithFrameメソッドでデータに直接アクセスする必要があります。

于 2012-02-14T18:12:09.630 に答える
0

この投稿、Hooligancatに非常に感謝しています。私のプロジェクトはこの問題で行き詰まっており、http: //www.timisted.net/blog/archive/custom-cells-でTimIstedの同じソリューションを見るのと同じくらい大変でした。 and-core-data/ わかりませんでした。

問題の優れた簡略化とソリューションのバージョンを読んだときだけ、ペニーが落ちました-私は非常に感謝しています!

于 2010-06-01T13:44:14.737 に答える