Выбор привязки между несколькими контроллерами представления в едином оконном интерфейсе

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

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

Подкласс NSWindowController имеет NSArrayController, привязанный к сущности Post, и доступный только для чтения метод доступа manageObjectContext, указывающий на [[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


person Justin Williams    schedule 03.03.2010    source источник


Ответы (2)


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

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

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

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

person Pierre Bernard    schedule 03.03.2010

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

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

person Jim McGowan    schedule 03.03.2010