Выбор привязки между несколькими контроллерами представления в одном интерфейсе окна - PullRequest
2 голосов
/ 03 марта 2010

У меня возникла проблема, заключающаяся в том, как подключить несколько контроллеров NSArrayController к двум контроллерам представления. Я хочу синхронизировать выбор в представлении таблицы списка источников, чтобы обновить значения во втором контроллере подробного представления.

Я использую Центральное руководство по сборке основных данных Cocoa Dev в качестве отправной точки, но разбил архитектуру так, что есть NSWindowController, который содержит два NSViewController: один для таблицы сообщений на слева и один для деталей сообщения справа.

Подкласс NSWindowController имеет NSArrayController, который связан с сущностью Post, и доступный только для чтения управляемый объектObjectContext, который указывает на [[NSApp delegate] managedObjectContext]

Затем я инициализирую два контроллера представления в методе windowDidLoad.

- (void)windowDidLoad
{
  static NSInteger kSourceListViewIndex = 0;
  static NSInteger kDetailViewIndex = 1;

  self.postsListsViewController = [[MDVCPostsListViewController alloc] initWithWindowController:self];  
    NSView *sourceListSplitViewContentView = [[self.splitView subviews] objectAtIndex:kSourceListViewIndex];
  NSView *sourceListView = [self.postsListsViewController view];
  [sourceListView setFrame:[sourceListSplitViewContentView bounds]];
  [sourceListView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
  [sourceListSplitViewContentView addSubview:sourceListView]; 

  // And now let's load the detail view.
  self.postDetailViewController = [[MDVCPostDetailViewController alloc] initWithWindowController:self];
    NSView *detailSplitViewContentView = [[self.splitView subviews] objectAtIndex:kDetailViewIndex];
  NSView *detailView = [self.postDetailViewController view];
  [detailView setFrame:[detailSplitViewContentView bounds]];
  [detailView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
  [detailSplitViewContentView addSubview:detailView]; 
}

MDVCPostsListViewController имеет NSArrayController, связанный с сущностью Post, и его контекст управляемого объекта, связанный с контекстом управляемого объекта контроллера родительского окна (все через Interface Builder)

MDVCPostDetailViewController имеет NSObjectController, связанный с контекстом управляемого объекта контроллера окна, и объект содержимого, связанный с контроллером окна через postsListsViewController.postsArrayController.selection. Это похоже на действительно отвратительный хак.

Как получить, чтобы изменение выбора в табличном представлении MDVCPostsListViewController обновляло выбранные значения в MDVCPostDetailViewController? Я чувствую, что я рядом, но я не уверен, чего не хватает или какой лучший маршрут выбрать. Я чувствую, что привязка postsListsViewController.postsArrayController.selection чрезвычайно хакерская. Надеюсь, есть лучший способ.

Я загрузил свой пример проекта, который демонстрирует это для тех, кто предпочитает смотреть на код, а не просто читать описания. Вы можете взять его с моего сайта по адресу http://www.secondgearsoftware.com/attachments/stackoverflow_objectcontroller.zip

Ответы [ 2 ]

3 голосов
/ 03 марта 2010

Как вы ожидаете, что каждый оконный контроллер обнаружит контроллер главного окна?

С первого взгляда на проект, кажется, вы просто добавили экземпляр MDVCMainWindowController в каждую NIB. Это будут отдельные экземпляры от того, который фактически запускает главное окно.

Вам нужно привязать вашу таблицу selectionIndexes из списка источников к контроллеру массива Post. В противном случае выбор не будет известен на уровне контроллера.

Я бы предложил переместить контроллер массива в контроллер главного окна. В вашем методе windowDidLoad вы можете передать его как в список, так и в подробный вид. Список связывался бы с упорядоченными объектами и выборочными индексами, а подробный вид связывался бы с selection.someKey.

1 голос
/ 03 марта 2010

Проблема связана с привязкой объекта содержимого экземпляра NSObjectController в подробном представлении xib. Ваш контроллер массива в xib представления списка правильно публикует уведомления KVO (проверьте это, заставив экземпляр MDVCPostDetailViewController наблюдать это с KVO), поэтому я не уверен почему, но по какой-то причине контроллер объектов не отвечает на них.

Тем не менее, есть несколько разных подходов, которые можно использовать. Вы можете избавиться от контроллера объекта и связать текстовые поля и т. Д. В xib подробного представления непосредственно с контроллером массива (File's Owner.windowController.postsListsViewController.postsArrayController.selection.whothing). В качестве альтернативы вы можете сохранить контроллер объекта и заставить свой контроллер детального просмотра наблюдать свойство выбора контроллера массива и «вручную» устанавливать свойство объекта содержимого контроллера объекта при изменении выбора.

...