2013-08-30 3 views
9

У меня есть простое приложение, в котором перечислены некоторые модели в NSTableView.Программно добавляя столбцы (с привязками) к NSTableView на основе представления?

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

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

Для простоты предположим эту установку:

  1. Объекты модели простые объекты с помощью всего одного свойства NSString: name
  2. AppDelegate имеет свойство NSArray (models), который имеет ряд модели экземпляров.
  3. Объект NSArrayController content привязан к массиву models делегата приложения.
  4. NSTableView's content привязан к контроллеру массива arrangedObjects.
  5. первой колонка таблицы связана (в МБ), чтобы отобразить name свойства, ячейка → значение т.е. столбец → ячейка таблицы вида → статический текст представления таблицы обязано представление таблицы клетки objectValue.name

Это, насколько я знаю, прямолинейно и по книге, и это работает как шарм.

Но ... Как добавить дополнительные столбцы?

Чтобы добавить столбец программно (сохранить его простым, давайте просто скажем, этот новый столбец должен также просто отобразить name свойства, так же, как столбец, который уже есть), я думаю, что я сделаю что-то подобное в приложение делегат:

NSTableColumn* newColumn = [[NSTableColumn alloc] initWithIdentifier:@"newColumn"]; 

// do binding magic somehow 
// [[newColumn dataCell] bind:NSValueBinding toObject:??? withKeyPath:??? options:nil]; 

[self.table addColumn:newColumn]; // the table's connected with an IBOutlet 

Я пробовал так много комбинаций связывания из/в ячейку данных, таблицы, столбец, контроллер массива, сам массив, а также все манера keypaths, но ничего не работает. Новый столбец добавлен просто отлично, но он никогда не заселен.

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

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

Я мог бы сделать все это, реализовав NSTableViewDataSource и «вручную» подавая таблицу, но у меня есть все, что было настроено с привязками.

Любая помощь была бы принята с благодарностью.

ответ

4

Попробуйте так: -

NSString *akey = @"keyValue"; 
NSString *keypath = [NSString stringWithFormat:@"arrangedObjects.%@",akey]; 
NSTableColumn *tableColumn=[[NSTableColumn alloc]initWithIdentifier:@"newColumn"]; 

[tableView addTableColumn:tableColumn]; 
[tableColumn bind:NSValueBinding toObject:yourArrayController withKeyPath:keypath options:nil]; 
NSMutableDictionary *dc=[NSMutableDictionary dictionary]; 
[dc setObject:@"textValue" forKey:@"keyValue"]; 
[yourmutableArray addObject:dc]; 
[self setYourmutableArray:yourmutableArray]; 

Пожалуйста, обратите внимание: - ваш изменяемый массив должен связываться с arraycontroller только тогда он будет заполнять данные

+0

Извините, не работает; попробовал. Связывание столбца работает только для сотовых таблиц. Не основанные на просмотре таблицы. – Flambino

2

Вы должны связываться с подвидами из NSTableCellView колонны с использованием этого метод делегата:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 
{ 
    // Get cell view - NSTableCellView 
    // This can be a prototype loaded from the table view or from another nib 
    // see : - registerNib:forIdentifier: 
    NSView *cellView = [tableView makeViewWithIdentifier:@"Cell1" owner:[tableView delegate]]; 

    // - subViewWithIdentifier is a simple category method that searches -subviews 
    NSView *subView = [cellView subViewWithIdentifier:@"TextField1"]; 
    [subView bind: NSValueBinding toObject:cellView withKeyPath: @"objectValue.name" options: nil]; 

    subView = [cellView subViewWithIdentifier:@"TextField2"]; 
    [subView bind: NSValueBinding toObject:cellView withKeyPath: @"objectValue.address" options: nil]; 

    return cellView; 
} 

NSView метод категория:

- (NSView *)subViewWithIdentifier:(NSString *)theIdentifier 
{ 
    __block NSView *subView = nil; 
    [[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
#pragma unused(idx) 
     if ([[obj identifier] isEqualToString:theIdentifier]) { 
      subView = obj; 
      *stop = YES; 
     } 
    }]; 
    return subView; 
} 
Смежные вопросы