Atualização VINCULADAS dicionário com base no valor editado do NSTextFieldCell
-
11-09-2019 - |
Pergunta
Eu estou trabalhando em portar algum código antigo (10.2 era) a partir NSCoding / plist baseado arquivar a usar Core Data. Eu tenho um NSOutlineView com um NSTextFieldCell personalizado. A vista de destaques está vinculado a um NSTreeController para fornecer os dados.
As ligações modelo se parece com isso:
NSTreeController: Gerenciado Contexto Object -> Controller.managedObjectContext
NSTableColumn de NSOutlineView Valor -> Árvore Controlador: arrangedObjects: itemDictionary
O NSOutlineView tem um costume NSTextFieldCell subclasse que adiciona uma imagem ao lado do campo de texto, por isso estou passando os valores da NSManagedObject a ele como um NSMutableDictionary chamado itemDictionary para que eu possa puxar e definir o título e IsChecked valores-chave.
Onde eu estou correndo em questões está atualizando o valor do campo de texto e passando esse valor de volta mudou a minha instância do objeto gerenciado. Depois que o usuário clica duas vezes sobre o valor título e edita-o, ele é passado para -(id)objectValue
, mas eu não tenho certeza que o próximo passo é obter a atualização propagada para o meu exemplo NSManagedObject. O código que eu tenho até agora para a leitura e definir valores em meu subclasse NSTextFieldCell está abaixo:
- (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];
}
Solução
Eu perguntei ao redor, e esta é a recomendação alguém me deu; parece razoável.
Em sua subclasse NSCell, em qualquer método é chamado pelo ciclo de eventos sobre a criação de um novo valor, fazer algo como isto:
- (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]];
}
Este é bastante código genérico que utiliza a informação de ligação disponíveis na coluna da tabela para obter o objeto modelo e caminho chave para que as alterações devem ser empurrados, e usar genérico KVC para empurrar as alterações. Ele deve funcionar para ambos os pontos de vista de tabela e de contorno, bem como para objetos de modelo arbitrárias, Núcleo de Dados ou não.
Outras dicas
Eu provavelmente abordar isso de uma maneira diferente, através da aplicação do método delegado outlineView:willDisplayCell:forTableColumn:item:
, e definindo a propriedade isChecked da célula lá, em vez de dentro da subclasse celular. Você, então, apenas ligam a coluna diretamente para arrangedObjects.title, de modo que o padrão mecanismo editar iria cuidar de definir a propriedade na instância objeto gerenciado.
IIRC, o item
parâmetro que se passou realmente será uma instância NSTreeNode cuja propriedade representedObject lhe dará o exemplo NSManagedObject para essa linha, para que possa obter qualquer informação que você precisa de lo dessa forma.