2009-08-24 8 views
4

Kann jemand hier Zellen in NSOutlineView editierbar machen? Ich benutze den Sampe-Code von Apple und ich kann es nicht funktionieren.NSOutlineView-Zeilen können bearbeitet werden

Ich versuche, es einzurichten, so dass, wenn Sie zweimal schnell nacheinander auf eine Zelle in der NSOutlineView klicken, die Zelle bearbeitet werden kann, damit der Benutzer den Text in der Zelle aktualisieren kann. (In der gleichen Weise, wie es in xcode und Mail und so weiter funktioniert).

Ich schließe den Großteil des restlichen Codes dieses Controllers in die vergebliche Hoffnung ein, dass jemand sehen kann, was ich falsch mache, das ist sehr frustrierend. Ich weiß shouldEditTableColumn wird aufgerufen, wie es die NSLog-Nachricht bei Doppelklick zurückgibt.

@implementation DisplayHierarchyController 
- (void)awakeFromNib { 
    // cache the reused icon images 
    folderImage = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] retain]; 
    [folderImage setSize:NSMakeSize(16,16)]; 
    objectImage = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericPreferencesIcon)] retain]; 
    [objectImage setSize:NSMakeSize(16,16)]; 
    diagramImage = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericEditionFileIcon)] retain]; 
    [diagramImage setSize:NSMakeSize(16,16)]; 
    // 
    // Tell the outline view to use a special type of cell 
    //NSTableColumn *tableColumn = [[outline tableColumns] objectAtIndex: 0]; 
    //ImageTextCell *imageTextCell = [[[ImageTextCell alloc] init] autorelease]; 
    //[imageTextCell setEditable:YES]; 
    //[tableColumn setDataCell:imageTextCell]; 
    // 
    [[[outline tableColumns] objectAtIndex: 0] setEditable: YES]; 
} 
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item { 
    NSLog(@"edit %@", tableColumn); 
    return YES; 
} 
- (NSCell *)outlineView:(NSOutlineView *)outlineView dataCellForTableColumn:(NSTableColumn *)tableColumn item:(id)item { 
    ImageTextCell *imageTextCell = [[[ImageTextCell alloc] init] autorelease]; 
    [imageTextCell setEditable:YES]; 
    return imageTextCell; 
} 
// Returns the object that will be displayed in the tree 
- (id)outlineView: (NSOutlineView *)outlineView child: (int)index ofItem: (id)item { 
    if(item == nil) 
     return [[document children] objectAtIndex: index]; 
    if([item isKindOfClass: [Item class]]) 
     return [[item children] objectAtIndex: index]; 
    return document; 
} 
- (BOOL)outlineView: (NSOutlineView *)outlineView isItemExpandable: (id)item { 
if([item isKindOfClass: [Item class]]) 
    return [[item children] count]>0; 
return NO; 
} 
- (int)outlineView: (NSOutlineView *)outlineView numberOfChildrenOfItem: (id)item { 
    if(item == nil) 
     return document.children.count; 
    if([item isKindOfClass: [Item class]]) 
     return [[item children] count]; 
    return 0; 
} 
- (id)outlineView: (NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { 
    if([item isKindOfClass: [Item class]]) 
     return [item name]; 
    return @"n/a"; 
} 
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { 
    NSLog(@"setObjectValue called"); 
} 
- (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { 
    [cell setEditable: YES]; 
    [cell setAllowsEditingTextAttributes: YES]; 
    [(ImageTextCell*)cell setImage: objectImage]; 
} 
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor { 
    return YES; 
} 
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { 
    if ([[fieldEditor string] length] == 0) { 
     // don't allow empty node names 
     return NO; 
    } else { 
     return YES; 
    } 
} 
@end 
+1

"Ich kann es anscheinend überhaupt nicht schaffen." Was meinst du damit? Bitte bearbeiten Sie Ihre Frage genauer. –

+0

Hoffentlich macht es das klarer. Ich möchte auf eine Zeile doppelklicken, um die Bearbeitung dieser Zeile zu aktivieren. – Jacob

+2

Ich mache mehr Studie darüber, wie man dies zum Funktionieren bringt, die Apple-Dokumentation sagt: "Eine Gliederungsansicht erbt viel von ihrem Verhalten von ihrer Elternklasse, NSTableView .... ..oder weitere Informationen finden Sie in der Programmieranleitung zur Tabellenansicht. " Ein NSTableView hat diese Methode "(BOOL) tableView: (NSTableView *) aTableView shouldEditTableColumn: (NSTableColumn *) aTableColumn Zeile: (NSInteger) rowIndex" aber ich kann nicht in der Lage sein, es zu meinem Controller in einer Weise hinzuzufügen, die es bekommt namens. – Jacob

Antwort

3

Ive gerade entdeckt, dass ich es "vortäuschen kann", indem ich die shouldEditTableColumn ändere. Es ist wirklich nicht ideal, aber es funktioniert. Nach so vielen Stunden versuchen, es zur Arbeit zu bringen, zumindest ist das etwas:

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item { 
    NSLog(@"edit %@", tableColumn); 
    [outline editColumn:0 row:[outline selectedRow] withEvent:[NSApp currentEvent] select:YES]; 
    return YES; 
} 
+0

Dies ist technisch nicht die richtige Antwort, aber es ist das nächste, was ich finden könnte, um es zum Laufen zu bringen. Es funktioniert nicht ganz richtig, aber es ist besser als nichts, das ist sicher! – Jacob

6

Ist die Spalte selbst als bearbeitbar festgelegt? Normalerweise würden Sie dies in IB tun.

Haben Sie auch the outlineView:setObjectValue: method in Ihrer Datenquelle implementiert?

+1

Wenn ich durch Klicken auf die Zelle im Interface Builder als editierbare gesetzt. Ich bin jedoch über die Zellen mit der benutzerdefinierten Zelle, die das Bild hat, nicht sicher, ob das relevant ist. Ich bin mir auch nicht sicher, was gehen soll in setObjectValue (es ist nicht klar aus der Dokumentation) :( – Jacob

+3

Ich habe die Zelle nicht gesagt, sagte ich die Spalte. Es hat eine eigene editierbare Checkbox.Wie für 'setObjectValue:': Hier nehmen Sie die Änderung, die der Benutzer vorgenommen hat, und wenden sie auf Ihr Modell an. Es ist die umgekehrte Richtung von "objectValue:", die das Modell untersucht und diese Informationen der Gliederungsansicht bereitstellt, um sie dem Benutzer anzuzeigen. –

+1

Doh, tut mir leid, dass ich falsch gelesen habe, was du geschrieben hast. Die NSTableColumn ist als editierbar markiert (es scheint, dass dies der Standard wäre, da ich es nicht angekreuzt habe) – Jacob

1

Ich fand einen Weg um dies. Setze die Datenzelle für die Spalte in IB (programmgesteuert in watchFromNib sollte auch funktionieren). Ich benutze tatsächlich 2 verschiedene benutzerdefinierte Zellklassen. Meine Lösung:

NSCell *cell = [tableColumn dataCellForRow: [outlineView rowForItem: item]]; 

if ([item isKindOfClass: [NSString class]]) 
    return [[[ShadowTextCell alloc] initTextCell: [cell stringValue]] autorelease]; 
return cell; 
8

Ich weiß, dass dies eine sehr alte Post, aber wenn jemand das gleiche Problem auftritt, kann dies zu Code im Zusammenhang kann kein Problem sein. Für meinen Fall handelte es sich um ein Problem, das mit einem in der XIB selbst gesetzten Wert zu tun hatte.

Nehmen wir an, Sie haben den gesamten Apple-Code kopiert, und Sie haben NSOutlineView installiert und ausgeführt, und einige noch nicht editierbare, gehen Sie zu Ihrem XIB und legen Sie die folgende Einstellung des NSTextField der Zelle Sie möchten bearbeitet werden können. In meinem Fall wurde die Verhaltenseinstellung standardmäßig auf keine festgelegt. Vielleicht ist es das gleiche Problem für Sie

enter image description here

Beifall.

+0

Danke! Das war das Problem, das ich auch hatte. Ich war so konzentriert darauf, einen "Bug" in meinem Code zu beheben, von dem ich nicht dachte, dass er IB überprüfen sollte. – sapi

+0

Dies ist immer noch in Xcode8 und Swift 3 mit view-based outlineViews der Fall, wo sentEditTableColumn nicht aufgerufen wird. Guter Fang. –

Verwandte Themen