【问题标题】:How do i make a simple view-based NSOutlineView?如何制作一个简单的基于视图的 NSOutlineView?
【发布时间】:2012-04-22 11:28:23
【问题描述】:

出于学习目的,我想将基于单元格的 NSOutlineView 转换为基于视图的,

基本上我想要以下内容:

  • 我想要一个“图像和文本表格单元格视图”而不是普通单元格
  • 图片可以是常用的 NSApplicationIcon,文本可以是“hello world”:)
  • 我想不使用绑定和NSTreeController

这是“世界上最简单的 NSOutlineView”示例http://www.cocoasteam.com/Cocoa_Steam/Worlds_Simplest_Demo.html

我想知道是否有人可以修改它以使其基于视图并像我上面所说的那样工作:) :)

我已经尝试查看苹果示例,并在互联网上的其他地方搜索,但我仍然无法使用它 - 所以提前非常感谢 :)

【问题讨论】:

    标签: objective-c cocoa nsoutlineview


    【解决方案1】:

    我创建了一个小示例项目,它就是这样做的。

    • 显示项目列表
    • 以主从方式编辑项目
    • 删除和添加项目
    • 绑定的使用

    在 github 上查看 besi/mac-quickies。 大部分东西要么在 IB 中完成,要么可以在 AppDelegate 中找到

    【讨论】:

    • 这是一个简单易学的例子。谢谢。
    【解决方案2】:

    好的,所以你想要一个带有ImageAndTextCell 单元格的NSOutlineView,对吧?

    让我们做一个最典型的例子:一个简单的文件浏览器。

    我们需要什么:

    • NSOutlineView(将大纲添加到您的 AppDelegate,如 fileOutlineView
    • 使用以下标识符在大纲中创建 3 列(在 Interface Builder 中设置它们):NameColumnSizeColumnModifiedColumn

    现在,至于其余部分,我将以编程方式完成所有操作,以便您对正在发生的事情有一个很好的了解...

    如何设置(例如在- (void)awakeFromNib):

    // set the Data Source and Delegate
    [fileOutlineView setDataSource:(id<NSOutlineViewDataSource>)self];
    [fileOutlineView setDelegate:(id<NSOutlineViewDelegate>)self];
    
    // set the first column's cells as `ImageAndTextCell`s
    ImageAndTextCell* iatc = [[ImageAndTextCell alloc] init];
    [iatc setEditable:NO];
    [[[fileOutlineView tableColumns] objectAtIndex:0] setDataCell:iatc];
    

    连接点:

    /*******************************************************
     *
     * OUTLINE-VIEW DATASOURCE
     *
     *******************************************************/
    
    - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
    {        
        if ([item isFolder])
            return YES;
        else
            return NO;
    }
    
    - (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
    {    
        if (item==nil)
        {
            // Root
            return [[filePath folderContentsWithPathAndBackIgnoringHidden] count];
        }
        else
        {        
            if ([item isFolder])
            {
                return [[item folderContentsWithPathAndBackIgnoringHidden] count];
            }
            else
            {
                return 0;
            }
        }
    }
    
    - (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
    {
        if (item == nil)
        { 
            // Root
            return [[filePath folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index];
        }
    
        if ([item isFolder])
        {
            return [[item folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index];
        }
    
        // File
        return nil;
    }
    
    - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item
    {          
        if ([[theColumn identifier] isEqualToString:@"NameColumn"])
        {
            return [item lastPathComponent];
        }
        else if ([[theColumn identifier] isEqualToString:@"SizeColumn"])
        {
            if ([item isFolder]) return @"--";
            else return [NSString stringWithFormat:@"%d",[item getFileSize]];
        }
        else if ([[theColumn identifier] isEqualToString:@"ModifiedColumn"])
        {
            if ([item isFolder]) return @"";
            else return [NSString stringWithFormat:@"%@",[item getDateModified]];
        }
    
        // Never reaches here
        return nil;
    }
    
    /*******************************************************
     *
     * OUTLINE-VIEW DELEGATE
     *
     *******************************************************/
    
    - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
    {
        return YES;
    }
    
    - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item
    {
        return NO;
    }
    
    - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
        [cell setDrawsBackground:NO];
    
        if ([item isFileHidden]) [cell setTextColor:[NSColor grayColor]];
        else [cell setTextColor:[NSColor whiteColor]];
    
        if ([[tableColumn identifier] isEqualToString:@"NameColumn"])
        {
            if ([item isFolder])
                [cell setImage:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] size:15.0];
            else
                [cell setImage:[[NSWorkspace sharedWorkspace] iconForFile:item] size:15.0];
    
            if ([item isFileHidden])
            {
                [cell setFileHidden:YES];
            }
            else
            {
                [cell setFileHidden:NO];
            }
    
        }
    
    }
    

    提示: ImageAndTextCell 类可以在 here 中找到。您还会注意到我正在使用的其他一些方法,显然 Cocoa 不支持这些方法(例如 isFileHiddenisFolderfolderContentsWithPathAndBackIgnoringHidden),但自己实现它们并不难......) p>

    【讨论】:

    • 我不明白这是怎么回事。 ImageAndTextCell 是 NSCell 类型,而不是 NSView。问题是关于基于视图的 NSOutlineView。您的示例只是创建一个自定义的 NSCell 子类,我们多年来一直能够这样做。对于 NSTableView 有很多例子来说明如何使用 NSView 而不是 NSCell。看起来很像iOS。遗憾的是,我还没有找到任何 NSOutlineView 示例。
    • @Adam- 基于视图的表使用 NSTableCellViews 作为它们的视图。从那里您可以向它们添加任何内容。 Dr.Kameleon 所说的完全正确。基于视图的表格的整体观点是,您可以添加任何您想要的视图对象(无论是单元格、按钮、图像...随便)
    • 这不是关于创建基于视图的大纲视图。
    【解决方案3】:

    将视图返回到 OutlineView 列而不是使用返回 objectValue 的数据源方法:

    - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item
    

    使用返回视图的数据源方法!!!!!!!!!:

    - (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
    

    其他一切都是一样的(最小 req 是前三个数据源方法,您不需要委托方法)但是, 你不能使用 willdisplaycell 它只调用基于 cell ,在 viefortablecolumn 方法中对视图执行所有操作,如下所示:

    if ([[tableColumn identifier] isEqualToString:@"YourColumnIdentifier"]){
        NSTableCellView *cell = [outlineView makeViewWithIdentifier:@"YourViewsIdentifier" owner:self];
        [cell.textField setStringValue:[(YourItem *)item name]];
        [cell.imageView setImage:[(YourItem *)item image]];
        return cell;
    }
    
    return nil;
    

    别忘了设置标识符,并将 OutlineView 设置为基于视图(在 IB 中 ...)。

    【讨论】:

    • 好的,这可行,但结果非常难看。 OutlineView 出现在视图后面:所以,这和基于视图的 NSTableView 不太一样。
    【解决方案4】:

    检查 TableViewPlayground,以及 WWDC 2011 的 View Based NSTableView Basic to Advanced

    【讨论】:

    • 谢谢,我已经检查了那个例子,我发现它太臃肿和混乱了。我认为我需要一个非常简单的例子来理解它(我对可可也有点陌生:P)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 2012-06-23
    • 2013-08-14
    • 1970-01-01
    相关资源
    最近更新 更多