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];
}
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top