Привязка основанного на представлении NSOutlineView к основным данным - PullRequest
16 голосов
/ 17 августа 2011

Я пытаюсь реализовать новый OutlineView на основе представления в виде списка источников в моем приложении Mac.Однако я не могу отобразить значения, поэтому я создал небольшое тестовое приложение из шаблона приложения Core Data и не могу заставить его работать прямо там.

Я определил два простых класса вмоя модель данных;давайте назовем их «Родитель» и «Ребенок». Parent имеет один атрибут "name" и одно отношение "children". name - необязательная строка, а children - необязательное отношение ко-многим к Child . Child имеет тот же атрибут «name» и отношение «один к одному» «parent», обратное children .Я сгенерировал пользовательские классы для них обоих и написал заглушку в Child для children , которая возвращает nil.

Я перетащил список источников из библиотеки объектовна мой XIB, и упал в Tree Controller.Путь к ключу Children контроллера дерева имеет значение «children», он находится в режиме «Имя объекта», с «Parent» в качестве имени объекта, «Подготавливается контент», а его контекст управляемого объекта установлен в контекст делегата приложения.Древовидный контроллер является источником данных представления структуры, и я связал текстовое представление ячейки данных с представлением ячейки таблицы с помощью ключевого пути «objectValue.name».

in -applicationDidFinishLaunching: Я создаю два Родительские экземпляры, один с Child , и присвойте свойство name каждому объекту.

Фактическая проблема

No text

Теперь, с этой настройкой, я получаю строки, отображаемые в исходном списке, но текстовые поля пусты, даже если они связаны.Я не думаю, что мне нужно делать что-то еще, поскольку я использую привязки, и я вполне уверен, что привязка к свойству objectValue - правильная вещь.Что не так?

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

Ответы [ 4 ]

25 голосов
/ 17 августа 2011

Ух ты, как я две недели назад задавал этот вопрос.

В любом случае, если вы чем-то похожи на меня, проблема в том,
для основанного на представлении NSOutlineViews необходимо реализовать

- (NSView *)outlineView:(NSOutlineView *)outlineView
     viewForTableColumn:(NSTableColumn *)tableColumn
                   item:(id)item;

метод делегата и возврат NSTableCellView, который вы установили,
или они просто дадут вам пустую строку. Самый простой способ сделать это - просто позвонить

[outlineView makeViewWithIdentifier:@"MyCell" owner:self]

замена MyCell на то, что вы ввели в качестве «Идентификатора элемента интерфейса пользователя»
в инспекторе личности для вашего NSTableCellView.

Objective-C:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
   return [outlineView makeViewWithIdentifier:@"MyCell" owner:self];
}

Swift:

func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
    return outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("MyCell"), owner: self)
}

ОБНОВЛЕНИЕ 2018-08-02:

На самом деле вам не нужно устанавливать делегата. Вот как у меня это работает (протестировано с NSTreeController, но должно работать и с NSArrayController):

  • Привязать каждый объект столбца к arrangedObjects (без пути ключа модели)
  • Привязать самый внутренний пользовательский вид (например, поле метки) к objectValue.yourCustomValue
  • Не обязательно, но если это не сработает, попробуйте установить идентификатор для столбца и для TableCellView. Убедитесь, что оба идентификатора идентичны. Повторите это для остальных столбцов с разными идентификаторами.

Снимок экрана: Привязки для NSOutlineView на основе представления

6 голосов
/ 14 января 2012

Как отметил Боаз выше, вам нужно реализовать метод Delegate для возврата представления.

Совершенно загадка, учитывая, что я не смог найти этот метод в Документах.

Что касается типа параметра (id)item, то это NSTreeControllerTreeNode, который является недокументированным подклассом NSTreeNode. Если вы разыгрываете его, вы можете получить объект ячейки и вернуть другое представление в зависимости от типа объекта или от того, какие атрибуты этого объекта определяют тип представления ячейки:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    NSTableCellView *view = nil;

    NSTreeNode *node = item;

    if ([node.representedObject isKindOfClass:[Group class]]) {
        view = [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
    } else {
        view = [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
    }

    return view;
}
4 голосов
/ 02 апреля 2012

Похоже, это изменение для Xcode 4 или около того. Построитель интерфейса добавляет два объекта NSTableCellView под NSOutlineView. Если вы удалите объекты NSTableCellView, вы вернетесь в более разумный (или хотя бы документированный) мир, в котором вам нужно будет реализовать методы:
outlineView:dataCellForTableColumn:item outlineView:willDisplayCell:forTableColumn:item

... или, по крайней мере, вы делаете, если хотите посмотреть список источников. В любом случае именно так настроен образец SourceView, и именно поэтому при попытке воссоздать образец SourceView, который вы можете получить в таком беспорядке.

В качестве альтернативы, если вы хотите продолжать использовать объекты NSTableCellView (которые весьма полезны), тогда вы можете:

  • привязать NSOutlineView 'Content' к вашему TreeController.arrangedObjects

  • связывает NSTextField (и / или NSImageView) в NSTableCellView с «представлением ячейки таблицы» с помощью ключевого пути модели objectValue.

1 голос
/ 11 октября 2013

Я создал небольшой пример проекта, в котором всплывающие окна также всплывают NSOutlineView, не с CoreData, но решающим фактором, как @ boaz-stuller, является то, что выбрана правильная ячейка (аналогично тому, как вы обрабатываете UITableViewCell s). в iOS.

Итак, в моем случае я реализовал метод следующим образом:

- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {

    if ([self isHeader:item]) {
        return [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
    } else {
        return [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
    }
}

Проверьте besi / mac-quickies на github. Большая часть материала либо делается в IB, либо находится в AppDelegate

screenshot

...