在一个NSTableviewColumn Cocoa OSX中有多个NSTableCellView

时间:2015-05-07 11:15:43

标签: objective-c macos cocoa nstableview

我正在尝试在一列中创建一个包含不同单元格的NSTableview。我在一列中设置了两个NSTableCellView,如下所示:

enter image description here

设置数据代码如下:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    // Get a new ViewCell

    // Since this is a single-column table view, this would not be necessary.
    // But it's a good practice to do it in order by remember it when a table is multicolumn.
    if( [tableColumn.identifier isEqualToString:@"BugColumn"] )
    {
           NSMutableDictionary *dic =(NSMutableDictionary*)[self.ArraRecentDataLoad objectAtIndex:row];

        if([[dic valueForKey:@"type"] isEqualToString:@"image/png"] || [[dic valueForKey:@"type"] isEqualToString:@"image/jpeg"])
        {

         ImageCell *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

                cellView = [[ImageCell alloc] initWithFrame:NSMakeRect(0, 0, 316, 313)];

                // This allows the cell to be reused.
                cellView.identifier =tableColumn.identifier;

            NSColor *orangeColor = [NSColor colorWithCGColor:[NSColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:1.0f].CGColor];

            // Convert to CGColorRef
            NSInteger numberOfComponents = [orangeColor numberOfComponents];
            CGFloat components[numberOfComponents];
            CGColorSpaceRef colorSpace = [[orangeColor colorSpace] CGColorSpace];
            [orangeColor getComponents:(CGFloat *)&components];
            CGColorRef orangeCGColor = CGColorCreate(colorSpace, components);
            [cellView.bgCellview setWantsLayer:YES];
            cellView.bgCellview.layer.masksToBounds= YES;
            cellView.bgCellview.layer.borderWidth=2;
            // Set border
            cellView.bgCellview.layer.borderColor = orangeCGColor;

            // Clean up
            CGColorRelease(orangeCGColor);

            return cellView;
        }
        else
        {
             HomeCell *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

            NSColor *orangeColor = [NSColor colorWithCGColor:[NSColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:1.0f].CGColor];

            // Convert to CGColorRef
            NSInteger numberOfComponents = [orangeColor numberOfComponents];
            CGFloat components[numberOfComponents];
            CGColorSpaceRef colorSpace = [[orangeColor colorSpace] CGColorSpace];
            [orangeColor getComponents:(CGFloat *)&components];
            CGColorRef orangeCGColor = CGColorCreate(colorSpace, components);
            [cellView.bgview setWantsLayer:YES];
            cellView.bgview.layer.masksToBounds= YES;
            cellView.bgview.layer.borderWidth=2;
            // Set border
            cellView.bgview.layer.borderColor = orangeCGColor;

            // Clean up
            CGColorRelease(orangeCGColor);

            return cellView;
        }

    }
    return nil;
}

但是在我的xib中,如果我拖动第二个单元格(imageCell),那么我的应用程序会因无法识别的选择而崩溃。如果我像上面的屏幕截图那样做,那么我无法加载第二个单元格,NSTableview中有空格。

我做了很多RND,但是我无法找到在单个列中使用不同单元格并根据条件数据加载的正确方法。

注意:

如果我在第一个条件中移除alloc单元格:

 cellView = [[ImageCell alloc] initWithFrame:NSMakeRect(0, 0, 316, 313)];
 cellView.identifier =tableColumn.identifier;

然后显示第一行的预定义标签,而不是第二行ImageCell预定义的iOS。

2 个答案:

答案 0 :(得分:2)

两个单元格视图需要具有不同的标识符。您必须手动分配至少一个。你不能让Xcode自动分配两者。 (我甚至不确定Xcode是否允许你按照这种方式配置。)

然后,当您致电[tableView makeViewWithIdentifier:... owner:self]时,您需要使用正确的标识符。这些调用中至多有一个可以使用表列的标识符。另一个必须使用手动分配的。

如果将两个单元格视图放在NIB中(带有单独的标识符)并使用[tableView makeViewWithIdentifier:... owner:self]获取它们,那么您不需要以编程方式分配/初始化(并且您不应该)。如果您希望以编程方式分配/ init,则必须为其分配不同的标识符。同样,您不能拥有两个具有相同标识符的单独单元格视图类型。

更新:让我以更简单的形式再试一次。这样做:

  • 在NIB中,选择“图像单元格”视图。在Identity检查器上,将标识符设置为“ImageCell”。
  • 在您的代码中,对于图片分支,请执行ImageCell *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self];而不是使用表格列标识符。
  • 删除以下两个语句,这两个语句分配ImageCell类的新实例并设置其identifier属性。

因此,代码应如下所示:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    // Get a new ViewCell

    // Since this is a single-column table view, this would not be necessary.
    // But it's a good practice to do it in order by remember it when a table is multicolumn.
    if( [tableColumn.identifier isEqualToString:@"BugColumn"] )
    {
        NSMutableDictionary *dic =(NSMutableDictionary*)[self.ArraRecentDataLoad objectAtIndex:row];

        if([[dic valueForKey:@"type"] isEqualToString:@"image/png"] || [[dic valueForKey:@"type"] isEqualToString:@"image/jpeg"])
        {
            ImageCell *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self];

            NSColor *orangeColor = [NSColor colorWithCGColor:[NSColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:1.0f].CGColor];
            // ...

答案 1 :(得分:1)

首先查看从nib查看基表视图。然后在viewfortablecolumn中放置像图像一样的条件,然后检查第一个视图(图像单元格或家庭单元格使其简单的NSView)可用于图像类型然后使用它或使用makeviewusingidentifire或使用什么,并返回该视图。在第二个条件下,你也是这样做的。

每次调用此方法时,它将首先检查它想要的哪种类型的视图(此特定的图像单元格或家庭单元格),然后检查它是否在内存中可用,如果没有则使用它然后分配并使用它。

如果有任何问题,请告诉我。 Sry for bad English