ユーザーが多くの情報をセクションに整理する Core Data アプリを作成しようとしています。ポップアップ メニューと境界線のないボックスを持つメインの xib があります。そのボックスに、ポップアップ ボタンから選択されたセクションのビューを含む別の xib が読み込まれます。
補助窓の一種である 2 番目の窓/パネルを作成することにしました。メイン ウィンドウにはサマリー テーブルが表示され、アクセサリ ビューでは、サマリー テーブルで現在選択されているものを取得してテキスト フィールドやグラフィカルな日付ピッカーに表示することで、データの入力が容易になります (ユーザーにテーブルに日付を入力するための正しい形式など)。また、いくつかのオプションのフィールドを保持し、統計を表示するため、それらが私のメインビューを詰まらせることはありません.
メインの xib の My Document.m には次のものがあります。
- (id)init
{
self = [super init];
if (self) {
viewControllers = [[NSMutableArray alloc] init];
accessoryViewControllers = [[NSMutableArray alloc] init];
ManagingViewController *vc;
ManagingViewController *accessoryVC;
vc = [[SummaryViewController alloc] init];
accessoryVC = [[SummaryAccessoryViewController alloc] init];
[vc setManagedObjectContext: [self managedObjectContext]];
[accessoryVC setManagedObjectContext: [self managedObjectContext]];
[viewControllers addObject: vc];
[accessoryViewControllers addObject: accessoryVC];
}
return self;
}
ポップアップ ボタンに表示されるその他の viewControllers/xib ファイルについても同様です。ポップアップで選択を行うと、その送信者タグが返され、タグを受け取る別のメソッドが呼び出され、vc 配列の objectAtIndex がメイン ウィンドウ ボックスに読み込まれ、accessoryVC 配列がアクセサリ ウィンドウに読み込まれます。実際の SummaryViewController.m には次のものがあります。
- (id) init {
self = [super initWithNibName: @"SummaryView" bundle:nil];
if (self) {
[self setTitle: @"Summary"];
}
return self;
}
すべてのビューを作成してから、バインディングを開始しました。メイン ウィンドウのテーブル内の列が ArrangeObjects.aaa にバインドされ、アクセサリ ビューのテキスト フィールドが selection.aaa にバインドされる場合がありますが、テーブルビューの選択が変更されても、その選択は変更されません。技術的には、2 つの別々の NSArrayController を使用しているためだと思います。
セカンダリ ウィンドウのデータがメイン ウィンドウに同期されている例を書籍で見たことがありますが、両方のウィンドウが同じ xib から取得されたために機能し、同じ NSArrayController を使用していました。私の質問は、これらのオプションのどれを使用できるかです。
1) NSArrayControllers を複数の xib ファイル間で同期させる方法はありますか?
2) SummaryAccessoryView.xib のカスタム ビューを SummaryView.xib に移動して、1 つの xib にメイン ウィンドウとアクセサリ ウィンドウの両方のビューが含まれるようにすることができます。次に、NSArrayController を共有します。しかし、ポップアップで 1 つのビューをメイン ウィンドウに、もう 1 つのビューをアクセサリ ウィンドウに配置するにはどうすればよいでしょうか。私の現在の方法はに依存して[super initWithNibName: SummaryView.xib]
いるため、どのビューを指定する方法がわかりません。
3) 1 ウィンドウ モデルに全体を掘り下げて再構築し、冗長なフィールドを削除して、余分なフィールドをメイン ビューの下部に配置できると思いますが、ユーザーはそれを非表示にしたり移動したりすることはできません。ユーザーが日付をテーブルビューにフォーマットするという問題が再び発生します...ユーザーがテーブルセルをクリックしたときにグラフィカルな日付ピッカーを表示する方法を知っていればうまくいくかもしれません。しかし、できれば 2 ウィンドウ モデルを維持したいと考えています。
オプション 1 または 2 の実行方法に関するアイデアはありますか?
編集:オプション3が機能しました:
まず、日付ピッカー (myDatePicker)、テーブル (myTable)、日付ピッカーを格納するポップオーバー (myPopover)、および NSArrayController (myArray) の ivar がいくつか必要です。また、私の例では、日付列が最初の列 (列 0) であり、IB で「日付」と名付けました。複数の日付 (開始日/終了日または 2 つのテーブルなど) がある場合は、#define を使用してフラグを設定し、必要な日付を特定する NSString ("tableAndColumn") を追加して、if ステートメントを if-複数の場合があるelse。
- (BOOL) tableView:(NSTableView *)tableView
shouldEditTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row {
if (tableColumn == [myTable tableColumnWithIdentifier: @"date"]) {
//tableAndColumn = myStartDate;
[myDatePicker setDateValue: [myArray valueForKeyPath: @"selection.date"]]; //this will set your date picker to the value already in the table column
NSRect rect = [myTable frameOfCellAtColumn: 0 row: [myTable selectedRow]];
[myPopover showRelativeToRect: rect ofView: myTable preferredEdge:NSMaxYEdge];
return NO;
// } else if (tableColumn == [myTable tableColumnWithIdentifier: @"endDate"]) {
// ...
} else {
return YES;
}
}
- (void) popoverWillClose:(NSNotification *)notification {
// if ([tableAndColumn isEqualToString: MyStartDate]) {
[myArray setValue: [myDatePicker dateValue] forKeyPath: @"selection.date"];
// } else if ([tableAndColumn isEqualToString: MyEndDate]) {
// ...
// }
}