Обновить связанный словарь на основе отредактированного значения NSTextFieldCell - PullRequest
0 голосов
/ 05 июня 2009

Я работаю над переносом некоторого древнего кода (эпоха 10.2) из ​​NSCoding / plist-архивирования в Core Core. У меня есть NSOutlineView с пользовательским NSTextFieldCell. Контурное представление привязано к NSTreeController для предоставления данных.

Модель привязок выглядит так:

NSTreeController: Контекст управляемого объекта -> Controller.managedObjectContext

NSTableColumn NSOutlineView Значение -> Контроллер дерева :ограмма объектов: itemDictionary

NSOutlineView имеет собственный подкласс NSTextFieldCell, который добавляет изображение рядом с текстовым полем, поэтому я передаю ему значения NSManagedObject в виде NSMutableDictionary с именем itemDictionary, чтобы я мог получить и установить значения ключей title и isChecked.

Я сталкиваюсь с проблемами при обновлении значения текстового поля и передаче этого измененного значения обратно в мой экземпляр управляемого объекта. После того, как пользователь дважды щелкнет значение заголовка и отредактирует его, оно будет передано -(id)objectValue, но я не уверен, что следующим шагом будет распространение обновления в мой экземпляр NSManagedObject. Код, который у меня есть для чтения и установки значений в моем подклассе NSTextFieldCell, приведен ниже:

- (void)setStringValue:(NSString *)aString {
  [super setObjectValue:aString];
}

- (void)setObjectValue:(id <NSCopying>)anObject {  
  id cellValues = anObject;

  [super setObjectValue:[cellValues valueForKey:@"title"]];
  [self setCheckState:[[cellValues valueForKey:@"isChecked"] integerValue]];
}

- (id)objectValue {
  return [super objectValue];
}

Ответы [ 2 ]

3 голосов
/ 08 июня 2009

Я спросил, и это рекомендация, которую кто-то дал мне; это выглядит разумно.

В вашем подклассе NSCell, в любом методе, который вызывается циклом событий при установке нового значения, сделайте что-то вроде этого:

- (void)whateverMethodInCellSubclassIsTriggeredByEventLoop:(id)value {
    NSTableView *tableView = [self controlView];
    NSTableColumn *column = [[tableView tableColumns] objectAtIndex:[tableView editedColumn]];
    NSInteger rowIndex = [tableView editedRow];
    NSDictionary *bindingInfo = [column infoForBinding:NSValueBinding];
    id modelObject = nil;

    if ([controlView isKindOfClass:[NSOutlineView class]]) {
        NSTreeNode *item = [outlineView itemAtRow:rowIndex];
        modelObject = [item representedObject];
    } else if ([controlView isKindOfClass:[NSTableView class]]) {
        NSArrayController *controller = [bindingInfo objectForKey:NSObservedObjectKey];
        modelObject = [[controller arrangedObjects] objectAtIndex:rowIndex];
    }

    [modelObject setValue:value forKeyPath:[bindingInfo objectForKey:NSObservedKeyPathKey]];
}

Это довольно общий код, который использует информацию о связывании, доступную в столбце таблицы, чтобы получить объект модели и ключевой путь, на который должны быть переданы ваши изменения, и использовать универсальный KVC для передачи изменений. Он должен работать как для табличных и контурных представлений, так и для произвольных объектов модели, базовых данных или нет.

0 голосов
/ 05 июня 2009

Вероятно, я бы подошел к этому по-другому, реализовав метод делегата outlineView:willDisplayCell:forTableColumn:item: и установив там свойство isChecked для ячейки, а не из подкласса ячейки. Затем вы просто привязали бы этот столбец непосредственно к argordObjects.title, чтобы механизм редактирования по умолчанию позаботился об установке свойства для экземпляра управляемого объекта.

IIRC, параметр item, который вы передаете, будет фактически экземпляром NSTreeNode, свойство presentObject которого даст вам экземпляр NSManagedObject для этой строки, так что вы можете получить любую необходимую информацию из него таким образом.

...