在NSTableView中仅为填充的行绘制网格线?

时间:2011-04-09 17:57:58

标签: cocoa

如何仅为已填充的行在NSTableView中绘制网格线?当我将网格样式掩码设置为NSTableViewSolidHorizo​​ntalGridStyleMask时,它会为所有行绘制网格线,无论是否填充。

我正在寻找一些示例代码来执行此操作。

4 个答案:

答案 0 :(得分:44)

到目前为止,我觉得最适合我的是以下代码。只是欺骗原始的网格绘图代码,只在填充的行上绘制。

子类NSTableView,如果需要,并覆盖drawGridInClipRect:(NSRect)clipRect,如下所示:

- (void)drawGridInClipRect:(NSRect)clipRect
{
    NSRect lastRowRect = [self rectOfRow:[self numberOfRows]-1];
    NSRect myClipRect = NSMakeRect(0, 0, lastRowRect.size.width, NSMaxY(lastRowRect));
    NSRect finalClipRect = NSIntersectionRect(clipRect, myClipRect);
    [super drawGridInClipRect:finalClipRect];
}

答案 1 :(得分:14)

在Swift 3.1中,这就是你需要的所有东西:

import Cocoa

class GridClipTableView: NSTableView {

    override func drawGrid(inClipRect clipRect: NSRect) { }

}

答案 2 :(得分:2)

我认为您必须继承NSTableView并覆盖drawRow:clipRect:。另一种可能性是覆盖drawGridInClipRect:,但这有点笨拙,因为你必须手动挑出行。

这应该让你朝着正确的方向前进:

- (void)drawRow:(NSInteger)rowIndex clipRect:(NSRect)clipRect {
    // First do the default drawing
    [super drawRow:rowIndex clipRect:clipRect];

    // Check if there's content in any of the cells in this row
    BOOL doesHaveContent = NO;
    int numCols = [self numberOfColumns];
    int colIndex;
    for( colIndex = 0; colIndex < numCols; colIndex++ ){
        NSCell * cell = [self preparedCellAtColumn:colIndex 
                                               row:rowIndex];
        if( [cell objectValue] != nil ){
            doesHaveContent = YES;
            break;
        }
    }

    if( doesHaveContent ){
        NSRect rowRect = [self rectOfRow:rowIndex];
        NSBezierPath * gridPath = [NSBezierPath bezierPath];
        // Ignoring clipRect because this isn't a lot of drawing
        [gridPath moveToPoint:rowRect.origin];
        [gridPath lineToPoint:NSMakePoint(rowRect.origin.x + rowRect.size.width,
                                          rowRect.origin.y)];
        [gridPath moveToPoint:NSMakePoint(rowRect.origin.x,
                                          rowRect.origin.y + rowRect.size.height)];
        [gridPath lineToPoint:NSMakePoint(rowRect.origin.x + rowRect.size.width,
                                          rowRect.origin.y + rowRect.size.height)];
        [myGridColor set];
        [gridPath stroke];
        // You could also just do:
        // [myGridColor set];
        // [[NSBezierPath bezierPathWithRect:rowRect] stroke];
    }
}

另一种可能性是拥有自定义NSCell;如果有内容,每个单元格可以在自身周围绘制一个特殊边框。但是,如果行中的某些单元格为空,则不会在整行上绘制一条线。

答案 3 :(得分:1)

出于某种原因,这里列出的两个解决方案都不适合我。相反,我所做的是:

  1. 子类NSTableView并覆盖rectOfColumn:(请参见下文)。
  2. 在表格视图,其剪辑视图和其滚动视图上打开图层支持(此解决方案需要此功能)。

在我的测试中,它从macOS 10.9到10.15一直有效。

- (NSRect)rectOfColumn:(NSInteger)column
{
    NSRect value = [super rectOfColumn:column];

    NSInteger numberOfRows = [self numberOfRows];
    if (numberOfRows == 0) {
        value.size.height = 0;
    } else {
        NSRect firstRect = [self rectOfRow:0];
        NSRect lastRect = [self rectOfRow:numberOfRows - 1];

        value.size.height = NSMaxY(lastRect) - NSMinY(firstRect);
    }

    return value;
}