【问题标题】:Getting NSOutlineView rows to be editable让 NSOutlineView 行可编辑
【发布时间】:2010-11-22 05:39:29
【问题描述】:

这里有人知道如何使 NSOutlineView 中的单元格可编辑吗?我使用的是苹果的示例代码,但我似乎根本无法让它工作。

我正在尝试对其进行设置,以便当您在 NSOutlineView 中的一个单元格上快速连续单击两次时,该单元格变为可编辑,以便用户可以更新单元格内的文本。 (与它在 xcode 和 mail 等中的工作方式相同)。

我徒劳地包含了这个控制器的大部分其余代码,希望有人能发现我做错了什么,这非常令人沮丧。我知道 shouldEditTableColumn 被调用,因为它在双击时返回 NSLog 消息。

@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

【问题讨论】:

  • “我似乎根本无法让它工作。”你这是什么意思?请编辑您的问题,使其更具体。
  • 希望这能让它更清楚。我想双击一行以启用该行的编辑
  • 我正在做更多关于如何让它工作的研究,苹果文档说“大纲视图从其父类 NSTableView 继承了它的大部分行为......或更多信息,请参阅表视图编程指南。” NSTableView 确实有这种方法“(BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex”,但我似乎无法以它得到的方式将它添加到我的控制器中调用。
  • 这是一个委托方法,所以你需要成为委托。另外,你需要实现 NSOutlineView 版本:outlineView:shouldEditTableColumn:item:
  • 是的,在我绝望中,我两个都试过了! (:

标签: objective-c cocoa nsoutlineview


【解决方案1】:

我知道这是一篇很老的帖子,但如果有人遇到同样的问题,这可能与代码无关。就我而言,这是一个与 XIB 本身中设置的值有关的问题。

假设您已经复制了所有 Apple 代码,并且您的 NSOutlineView 已启动并运行,但有些仍然无法编辑,请转到您的 XIB 并设置您所在单元格的 NSTextField 的以下设置想要可编辑。在我的情况下,行为设置默认设置为 none。也许对你来说也是同样的问题

干杯。

【讨论】:

  • 谢谢!这也是我遇到的问题。我非常专注于修复代码中的“错误”,以至于我没想过要检查 IB。
  • 这在 Xcode8 和 Swift 3 中仍然是这种情况,基于视图的 outlineViews 不会调用 shouldEditTableColumn。很好的收获。
【解决方案2】:

列本身是否设置为可编辑?通常,您会在 IB 中执行此操作。

另外,您是否在数据源中实现了the outlineView:setObjectValue: method

【讨论】:

  • 当我点击进入界面生成器中的单元格时,它被设置为可编辑。然而,我用具有图像的自定义单元格覆盖单元格,不确定这是否相关。我也不确定 setObjectValue 应该包含什么(从文档中不清楚):(
  • 我没有说单元格,我说的是列。它有自己的可编辑复选框。至于setObjectValue::这就是您将用户所做的更改应用到您的模型的地方。这是objectValue: 的相反方向,它检查模型并将该信息提供给大纲视图以显示给用户。
  • Doh,对不起,我看错了你写的东西。 NSTableColumn 被勾选为可编辑(这似乎是默认设置,因为我没有勾选它)
【解决方案3】:

我刚刚发现我可以通过更改 shouldEditTableColumn 来“伪造”它。它确实不理想,但它确实有效。经过这么多小时试图让它工作,至少这是这样的:

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

【讨论】:

  • 这在技术上不是正确的答案,但它是我能找到的最接近它的东西。它工作得不太好,但总比没有好!
【解决方案4】:

我找到了解决这个问题的方法。为 IB 中的列设置数据单元格(以编程方式在 awakeFromNib 中也应该可以工作)。我实际上使用了 2 个不同的自定义单元类。我的解决方案:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多