如何在基于视图的NSTableView中添加行跨度?

5

我正在尝试使用Lion引入的基于视图的NSTableView来实现如下所示的表格布局。

对于基于单元格的NSTableView,有多种方法可供选择,例如模仿艺术列,但是这些方法并不适用于基于视图的表格视图。

思路是通过对象数组填充表格,在一列(或多列)跨越行中指示对象共享某些数据。 numberOfRowsInTableView:返回项目的总数(在附加图像的情况下为19)。

有人尝试过这样的方法吗?

布局

使用跨行显示的分组/部分

2个回答

5
我通过使用两个单独的NSTableView并使它们的NSScrollView的滚动同步来实现这一点。要了解如何同步多个滚动视图(具有确切子类代码),请阅读 Mac中的滚动视图编程指南-同步滚动视图 我有一个groupTableView,它有一列,显示代表组的视图。我还有一个itemTableView,它有代表组件的列。我使用相同的委托/数据源方法,通过if-else语句检查正在使用哪个NSTableView,并根据需要以正确的#行、单元格视图等做出响应。此外,我实现了以下委托方法,以调整组表视图的行高度,使其等于组中行的项目行高度之和:
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
    if (tableView == self.groupTableView) {
        NSUInteger firstRowIndexForGroup = ...;
        NSUInteger lastRowIndexForGroup = ...;
        CGFloat groupHeight = 0.0;
        for (NSUInteger currentRowIndex = firstRowIndexForGroup; currentRowIndex <= lastRowIndexForGroup; currentRowIndex++) {
            groupHeight += [self.itemTableView rectOfRow:lastRowIndexForGroup].size.height;
        }
        return groupHeight - [self.itemTableView intercellSpacing].height;
    } else {
        return self.itemTableView.rowHeight;
    }
}

每当表格视图需要一个分组视图时,您还必须调用-noteHeightOfRowsWithIndexesChanged:,因为高度会根据组中行数的变化而改变。

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    if (tableView == self.groupTableView) {
        GroupRowView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
        // configure view
        [tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndex:row]];
        return view;
    } else {
        ItemRowView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
        // configure view
        return view;
    }
}

我在组表视图上禁用了行选择以及水平和垂直滚动条。我还为两个表视图都设置了实线的水平网格线。最后,我将组表视图直接放置在项目表视图旁边,两者之间没有间隙,因此它看起来就像是单个表视图中的另一列。结果是一个完美的实现,两个表视图之间没有任何延迟。对于用户来说,它看起来就像是一个单独的表视图。

哇哦...这绝对是一个不会第一时间想到的解决方案!之前已经使用过同步滚动,所以我知道它是如何工作的。可能需要补充的一点是,如果组单元格被点击/选择,那么这将不得不“转发”选择到项目表视图的第一行。 - klotz
您还可以将组表视图拆分,以选择性地每个组包含两行。这样,您可以使顶部行浮动在其他行上方,因此如果您有一个大组,则组信息会一直浮动,直到最后一个组项滚动到屏幕外。 - user836263
你想到了什么方法来保持物品表的行与组表同步?如何防止物品表对其行进行排序,以使它们不与相邻的组对应? - erynofwales
@erynofwales 我依赖于分组进行排序。项目从未作为整体排序(项目将不会保持分组)。将分组作为整体排序,然后对每个组的项目进行排序是可以接受的。当对组进行更改时,两个表视图都会重新加载。我使用一个单独的数据源对象,封装对数据的访问,并公开像 -indexOfGroup: 和 -indexOfItem: 以及 -groupAtIndex: 和 -itemAtIndex: 这样的方法,在表视图的数据源方法中使用。在内部,数据源对象使用两个数组(一个用于组,一个用于项目)以提高速度和简单性。 - user836263

0
你能不能使用 NSOutlineView 代替呢?它是专门设计用于支持分组的。

但是,你如何将组值放入一个单元格中,使其高度成为所有子节点行的总高度,而不是使用它自己的行高呢? - klotz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接