默认[NSTableViewDelegate tableView:sizeToFitWidthOfColumn:]不会被调用

时间:2014-11-15 00:51:32

标签: objective-c macos cocoa nstableview

根据Apple's documentation on [NSTableViewDelegate tableView:sizeToFitWidthOfColumn:]

  

默认情况下,NSTableView迭代表中的每一行,访问一个   cell via preparedCellAtColumn:row:,并请求cellSize查找   适当的最大宽度。

     

为了获得准确的结果和性能,建议这样做   使用大表时实现方法。默认情况下,大   表使用蒙特卡罗模拟而不是迭代每一行。

这个默认行为正是我想要的,所以我选择不在我的NSTableViewDelegate中实现这个方法。但是,当我双击列的调整大小分隔符时,没有任何反应。我的表视图是基于视图的。

1 个答案:

答案 0 :(得分:0)

从OS X 10.10.2开始,双击列分隔符时,基于视图的表视图中的列仍然不会自动调整大小。

我实现了委托来对可见矩形的行以及下面和上面的50行进行采样。

- (CGFloat)tableView:(NSTableView *)tableView sizeToFitWidthOfColumn:(NSInteger)column
{
    // Note: Called on double-click of table columns separator
    // Note: As of 10.10.2, [NSTableView _sizeToFitWidthOfColumn] does nothing for view-based table views
    NSRect          visibleRect     = tableView.visibleRect;
    NSRange         rowRange        = [tableView rowsInRect:visibleRect];
    NSUInteger      numberOfRows    = tableView.numberOfRows;
    NSInteger       minRow          = rowRange.location;
    NSInteger       maxRow          = rowRange.location + rowRange.length;

    minRow  = MAX(0, minRow - 50);
    maxRow  = MIN(numberOfRows, maxRow + 50);

    NSTableColumn   *tableColumn    = [[tableView tableColumns] objectAtIndex:column];
    CGFloat         minWidth        = tableColumn.minWidth;
    CGFloat         maxWidth        = tableColumn.maxWidth;
    CGFloat         width           = minWidth;

    /*
     NSCell         *headerCell     = tableColumn.headerCell;

     if ([headerCell isKindOfClass:[NSCell class]]) {
        NSRect  bounds          = NSMakeRect(0.0f, 0.0f, maxWidth, headerCell.cellSize.height);
        CGFloat fittingWidth    = [headerCell cellSizeForBounds:bounds].width;

        if (fittingWidth > width) {
            width = fittingWidth;
        }
     }
     */
    for (NSInteger row = minRow; row < maxRow; row++) {
        NSTableCellView *tableCellView  = [tableView viewAtColumn:column row:row makeIfNecessary:YES];
        CGFloat         fittingWidth    = [tableCellView fittingSize].width;

        if (fittingWidth > width) {
            width = fittingWidth;

            if (width >= maxWidth) {
                break;
            }
        }
    }

    return MIN(maxWidth, width);
}