12

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

基本上我想要以下内容:

  • 而不是普通的单元格,我想要一个“图像和文本表格单元格视图”
  • 图片可以是股票 NSApplicationIcon,文字可以是“hello world”:)
  • 我想在不使用绑定的情况下做到这一点,并且NSTreeController

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

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

我试过看苹果的例子,并在互联网上的其他地方搜索,但我仍然无法让它工作 - 所以提前非常感谢:)

4

4 回答 4

9

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

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

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

截屏

于 2013-10-11T13:03:48.677 回答
8

好的,所以你想要一个NSOutlineView带有ImageAndTextCell细胞的,对吧?

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

我们需要什么:

  • 一个NSOutlineView(为您的 AppDelegate 设置一个大纲,如fileOutlineView
  • 使用以下标识符在大纲中创建 3 列(在 Interface Builder中设置它们):NameColumn、、、SizeColumnModifiedColumn

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

如何设置它(例如 in - (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];
        }

    }

}

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

于 2012-04-23T06:39:42.470 回答
1

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

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

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

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

其他一切都是一样的(最小的 req 是前三个数据源方法,你不需要委托方法)但是,你不能使用 willdisplaycell 它只为基于单元格调用,像这样在 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 中 ...)。

于 2013-11-29T07:42:58.453 回答
0

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

于 2012-04-10T08:23:50.043 回答