複数のXIBから1つのNSArrayControllerを使用する
-
19-08-2019 - |
質問
1つのNSArrayControllerの内容を、異なるXIBで定義された2つのウィンドウに表示する際に問題が発生しています。
メインウィンドウ(MainMenu.xib)には、NSArrayControllerにバインドされているNSTableViewがあります
2番目のXIBには、NSTableViewを含む別のウィンドウがあります。新しいNSArrayControllerを作成し、テーブルをそのNSArrayControllerのコンテンツにバインドしました。
両方のNSArrayControllersは、まったく同じNSArrayにバインドされています。
最初はすべて問題ありませんが、問題は、メインウィンドウでNSArrayControllerを使用してオブジェクトを配列に追加すると、データのセカンダリウィンドウのビューが更新されないことです。 NSArrayControllerは新しいオブジェクトを追加するために使用されなかったため、これは自分自身を更新する必要があることを認識していないためです。
私がやりたいのは、両方のウィンドウでNSArrayControllerのまったく同じインスタンスを使用することです。これにより、オブジェクトが配列に追加されると、両方のビューに変更が通知されます。
問題は、Interface Builderでこれを行う方法がわからないことです。 NSArrayControllerを別のNSArrayControllerにバインドできません(NSArrayにのみバインドできることを示すランタイムエラーが表示されます)。 NSArrayControllerをFile's OwnerのNSArrayControllerメンバーに接続しても、使用したいNSArrayControllerが完全に消去されるため、役に立ちません。
コードで自分でバインディングを設定できると思いますが、可能であればInterface Builderを使用する方が良いようです。 Interface Builderでこれを行う方法はありますか、それともすべて一緒に設定するより良い方法がありますか?
更新: Chuckの回答とコメントに応えて、次のことを試しました。 -NSTableViewのテーブルコンテンツをNSArrayControllerメンバーのarrangedObjectsにバインドしました(NSArrayController自体を使用した場合、ログにエラーが表示されました:<!> quot; [NSArrayController count]:unrecognized selector sent to instance <!> quot; ) -arrayController.arrangedObjects.propertyNameのモデルキーパスを使用して、テーブルの各列をファイルの所有者にバインドしました
これでも、テーブルの内容が更新されることはありませんでした。 NSArrayController自体ではなく、NSArrayControllerのarrangedObjectsにバインドしているからだと思います。しかし、NSArrayControllerに直接バインドすると、エラーが発生します。
通常、NSArrayControllerは<!> quot; Bind to <!> quot;から選択します。 ComboBoxでは、arrangedObjectsをコントローラーキーとして使用し、プロパティ自体をモデルキーパスとして使用します。この場合、それと同等のことを行う方法がわかりません-できれば。
上記のプロセスで何か間違ったことをしましたか?
解決
私が思いついた最良のオプションは、2番目のNSArrayController
にrearrangeObjects:
を呼び出して、管理している配列が変更されたことを通知することです。それは不格好に思えますが、動作します。
他のヒント
それらをIBのプロキシオブジェクトとして設定し、実際のコードをおそらくアプリデリゲートでインスタンス化するのはどうですか?
配列が追加されると、KVOを介して両方のNSArrayControllersを更新できます。秘Theは、KVOに準拠した方法で配列を観察して追加する必要があることです。
配列を所有するオブジェクトが必要な場合は、<!> quot; model <!> quot;と呼びましょう。配列はオブジェクトのキーでなければなりません。キー<!> quot; contentArray <!> quot;を呼び出しましょう。次に、追加または削除するときは、最初に<!> quot; model <!> quot;でmutableArrayForKeyを呼び出して、削除する必要があります。 <!> quot; contentArray <!> quot;を取得します。次に、配列からの追加/削除が機能するはずです。例:
Controller1はself.model.contentArrayにバインドされています
Controller2はself.model.contentArrayにバインドされています
//this method is on the "model" object
-(void)addContent(id content)
{
NSMutableArray* contentArr = [self mutableArrayForKey:@"contentArray"];
[contentArr addObject:content]; //this will trigger KVO notifications
}
別の方法として、次のように手動でKVO通知を行うこともできます。
-(void)addContent(id content)
{
[self willChangeValueForKey:@"contentArray"];
[m_contentArray addObject:content];
[self didChangeValueForKey:@"contentArray"];
}
2つのアレイコントローラを使用して、別のビューを介して更新するときに、1つのビューを更新しないようにする必要はありません。そうでない場合は、KVO通知がどこかで失われているようです。適切な変更通知を送信せずに、(おそらくNSArrayControllerサブクラスのadd:
メソッドで)配列を直接編集している可能性があります。