0

我有一个 NSScrollView,它设置为通过单击 IB 中滚动视图上的图层复选标记来支持图层。在该滚动视图中,我有一个 NSTableView。在那个 NSTableView 中,我使用自定义 NSTableRowView 在我的列之间的分隔线处绘制一条垂直的红线。我的 NSTableView 有 2 列。当我的滚动视图设置为支持图层时,每当我拖动列分隔线以使列更宽或更窄时,不会调用 drawBackgroundInRect,因此在拖动操作期间我的背景垂直线不会得到更新。

有解决方法吗?

这是我在 drawBackgroundInRect 中使用的代码:

- (void)drawBackgroundInRect:(NSRect)dirtyRect {

[super drawBackgroundInRect:dirtyRect];

NSGraphicsContext *nscontext = [NSGraphicsContext currentContext];

[nscontext saveGraphicsState];

CGContextRef context = (CGContextRef)[nscontext graphicsPort];

if (!self.isGroupRowStyle) {

    CGRect leftColumnRect = [(NSView *)[self viewAtColumn:0] frame];
    leftColumnRect.origin.y -= 1.0;
    leftColumnRect.size.height += 2.0;
    leftColumnRect.size.width += 1.0;

    // grey background

    CGContextSetGrayFillColor(context, 0.98, 1.0);
    CGContextFillRect(context, leftColumnRect);

    // draw nice red vertical line

    CGContextBeginPath(context);
    CGContextSetRGBStrokeColor(context, 0.6, 0.2, 0.2, 0.3);

    CGContextMoveToPoint(context, leftColumnRect.size.width + 1.5, 0);
    CGContextSetLineWidth(context, 1.0);
    CGContextAddLineToPoint(context, leftColumnRect.size.width + 1.5, leftColumnRect.size.height);
    CGContextStrokePath(context);

}
[nscontext restoreGraphicsState];
}

这是调整列大小时遇到​​的问题:

在此处输入图像描述

这就是我没有将滚动视图设置为支持图层时的样子:

在此处输入图像描述

谢谢!

4

1 回答 1

0

一年多后,我终于找到了一个正确的答案来回答我自己的问题。

诀窍是在调整 NSTableColumn 的大小时对可见行列表中的每一行调用 setNeedsDisplay。

这是我在 NSViewController 子类中使用的代码:

- (void)tableView:(NSTableView *)tableView isResizingTableColumn:(NSTableColumn *)tableColumn {
    NSRange range = [tableView rowsInRect:tableView.visibleRect];
    for (NSInteger row = range.location; row < (range.location + range.length); row++) {
        NSTableRowView *rowView = [tableView rowViewAtRow:row makeIfNecessary:NO];
        [rowView setNeedsDisplay:YES];
    }
}

我的 NSTableView 将我自己的 NSTableHeaderView 子类作为其标题视图。我将我的 NSViewController 设置为标题视图的委托,以便我可以跟踪用户何时调整大小。

TFRecordTableHeaderView.h:

#import <Cocoa/Cocoa.h>

@protocol TFRecordTableHeaderViewDelegate <NSObject>
- (void)tableView:(NSTableView *)tableView isResizingTableColumn:(NSTableColumn *)tableColumn;
@end

@interface TFRecordTableHeaderView : NSTableHeaderView
@property (nonatomic, assign) id<TFRecordTableHeaderViewDelegate>delegate;
@end

TFRecordTableHeaderView.m:

#import "TFRecordTableHeaderView.h"

@implementation TFRecordTableHeaderView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];

    if (self) {
        // Initialization code here.
    }

    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    // do some custom drawing here
}

// track resizing of the column as it happens
// from the docs: If the user is resizing a column in the receiver, returns the index of that column.

- (NSInteger)resizedColumn {
    NSInteger columnIndex = [super resizedColumn];

    if (columnIndex >= 0) {
        NSTableColumn *column = [self.tableView.tableColumns objectAtIndex:columnIndex];

        if ([self.delegate respondsToSelector:@selector(tableView:isResizingTableColumn:)]) {
            [self.delegate tableView:self.tableView isResizingTableColumn:column];
        }
    }

    return columnIndex;
}

@end

只需将 NSTableHeaderView 子类设置为 NSTableView 的标题视图。现在,每当您在标题中拖动一列时,都会调用 isResizingTableColumn 委托方法。您可以在 NSViewController 子类上实现 isResizingTableColumn。

现在,当您调整列的大小时,将调用 isResizingTableColumn,它将获取可见矩形的 NSTableRowViews,并将发送 setNeedsDisplay。这将导致刷新行并在拖动时调用 drawBackgroundInRect 方法。这反过来将刷新我的自定义垂直网格线。

所有这些都是为了避免在 NSTableView 上的顶部分组行上绘制垂直网格线。我认为这应该内置到 NSTableView 中。如果您的组部分标题中有文本并且在文本上方有一条垂直网格线,那看起来真的很糟糕。

现在我想了想,你可以在你的 NSTableHeaderView 子类上做这件事:

- (NSInteger)resizedColumn {
    NSInteger columnIndex = [super resizedColumn];

    if (columnIndex >= 0) {         
        NSRange range = [self.tableView rowsInRect:self.tableView.visibleRect];
        for (NSInteger row = range.location; row < (range.location + range.length); row++) {
            NSTableRowView *rowView = [self.tableView rowViewAtRow:row makeIfNecessary:NO];
            [rowView setNeedsDisplay:YES];
        }
    }

    return columnIndex;
}

就我而言,我是在我的 NSViewController 子类上做的,因为当我调整一个表列的大小时,我也在同样调整另一个列的大小。这是用另一个类似配置的表模拟页脚行,其中只有一行,因为 NSTableView 没有像 UITableView 那样的页脚概念。

于 2014-10-15T03:06:47.573 回答