Domanda

Sto lavorando sul porting del codice antico (10.2 epoca) dall'archiviazione base NSCoding / plist di utilizzare Core Data. Ho un NSOutlineView con un costume NSTextFieldCell. La vista struttura è associato a un NSTreeController di fornire i dati.

Il modello di attacchi si presenta così:

NSTreeController: Gestito Context Object -> Controller.managedObjectContext

NSTableColumn

di NSOutlineView Valore -> Regolatore Albero: arrangedObjects: itemDictionary

Il NSOutlineView ha un NSTextFieldCell sottoclasse personalizzata che aggiunge un'immagine accanto al campo di testo, in modo da sto passando i valori del NSManagedObject ad esso come un NSMutableDictionary itemDictionary chiamato in modo da poter tirare e impostare il titolo e IsChecked valori chiave.

Dove Sono in esecuzione in problemi sta aggiornando il valore del campo di testo e passando tale valore cambiato di nuovo alla mia istanza di oggetto gestito. Dopo che l'utente fa doppio clic sul valore del titolo e modifica di esso, si passa alla -(id)objectValue, ma non sono sicuro di quello che il passo successivo è quello di ottenere l'aggiornamento propagato al mio esempio NSManagedObject. Il codice che ho finora per la lettura e l'impostazione dei valori nel mio sottoclasse NSTextFieldCell è qui sotto:

- (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];
}
È stato utile?

Soluzione

Ho chiesto in giro, e questa è la raccomandazione qualcuno mi ha dato; sembra ragionevole.

Nel vostro sottoclasse NSCell, in qualsiasi metodo viene richiamato dal ciclo di eventi su impostazione di un nuovo valore, fare qualcosa di simile:

- (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]];
}

Questo è abbastanza codice generico che sfrutta le informazioni vincolante disponibili sul colonna della tabella per ottenere l'oggetto del modello e il percorso chiave a cui devono essere spinto le modifiche, e per uso generico KVC per spingere le modifiche. Dovrebbe funzionare sia per la tavola e delineare una vista così come per gli oggetti del modello arbitrari, Core Data o no.

Altri suggerimenti

Io probabilmente affrontare questo in un modo diverso, attuando il metodo delegato outlineView:willDisplayCell:forTableColumn:item:, e impostando la proprietà isChecked della cella lì, piuttosto che dall'interno della sottoclasse di cellule. Si potrebbe quindi semplicemente associare quella colonna direttamente a arrangedObjects.title, in modo che il meccanismo di modifica di default sarebbe preso cura di impostare la proprietà per l'istanza oggetto gestito.

IIRC, il parametro item si ottiene passato sarà effettivamente un'istanza NSTreeNode cui representedObject proprietà vi darà l'istanza NSManagedObject per quella riga, in modo da poter ottenere qualunque tipo di informazione da questo modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top