这是我的第一个问题,我会尽可能明确地做到这一点。
我想在基于视图的NSTableView中的选定行上绘制自定义渐变,同时添加细微的凸起效果。为此,我需要为所选行之前和之后的网格线使用较暗的颜色(例如,请参阅here)。我在 NSTableRowView 中覆盖drawSeparatorInRect:
方法来绘制所选行的自定义分隔线(使用isSelected
方法作为标记),但我不能对上面的内容执行相同操作/低于1(因为我在底部/顶部画线)。
我已经尝试了几种方法来告诉最近的一行,它应该绘制一个较暗的分隔线而没有成功,因为显示步骤不遵循相同的顺序(我在drawSeparatorInRect:
中使用NSLog检查它,并且它似乎当你滚动一点这个顺序改变)。因此,有时(主要是在滚动之后)该行不知道它应该使用更暗的颜色,因为它在所选择的之前绘制自己(我想在这一点上,所选行还没有意识到它被选中,否则我不明白发生了什么事。)
我尝试过的一些事情:
drawSeparatorInRect:
方法中,我尝试访问同级视图([superview subviews]
)并强制上一个/下一个视图再次绘制自己。NSTableView
子类,在 selectedIndexes 更改时直接修改最近的行。drawSeparatorInRect:
方法中绘制所选行之外的行,以显示here。请注意,我这样做了:行视图询问是否选择了上一个/下一个, nearestRowIsSelected 标志或外部调用方法来“强制”暗色。
我现在所拥有的是所选行绘制了顶部和底部边框,因此其中一个被放置在上一行/下一行行中......它很微妙但它仍然存在。
任何帮助都会受到欢迎。
提前谢谢。
!我没有发布任何代码,因为问题不存在(它只是用红色调用[NSBezierPath fillRect:rect]
),我想......所以我没有任何表现。
答案 0 :(得分:12)
我也试过这个并注意到drawSeparatorInRect:真的只能绘制它的底部分隔线,因为顶部分隔线的位置(与前一行的底部分隔线相同)是一个像素在行的clipRect之外(上方)。
但是,我通过子类化NSTableRowView并使用drawSeparatorInRect来实现它:如下所示:
- (void)drawSeparatorInRect:(NSRect)dirtyRect
{
// Define our drawing colors
NSColor *normalColor = [NSColor colorWithCalibratedWhite:0.76 alpha:1.0]; // Default separator color
NSColor *selectedTopColor = [NSColor colorWithCalibratedWhite:0.60 alpha:1.0]; // Color of the top separator line of selected row
NSColor *selectedBottomColor = [NSColor colorWithCalibratedWhite:0.60 alpha:1.0]; // Color of the bottom separator line of selected row
// Define coordinates of separator line
NSRect drawingRect = [self frame]; // Ignore dirtyRect
drawingRect.origin.y = drawingRect.size.height - 1.0;
drawingRect.size.height = 1.0; // Height of the separator line we're going to draw at the bottom of the row
// Get the table view and info on row index numbers
NSTableView *tableView = (NSTableView*)[self superview]; // The table view the row is part of
NSInteger selectedRowNumber = [tableView selectedRow];
NSInteger ownRowNumber = [tableView rowForView:self];
// Set the color of the separator line
[normalColor set]; // Default
if (([self isSelected]) && ((selectedRowNumber + 1) < [tableView numberOfRows])) [selectedBottomColor set]; // If the row is selected, use selectedBottomColor
if ((![self isSelected]) && (selectedRowNumber > 0) && (ownRowNumber == (selectedRowNumber-1))) [selectedTopColor set]; // If the row is followed by the selected row, draw its bottom separator line in selectedTopColor
// Draw separator line
NSRectFill (drawingRect);
// If the row is selected, tell the preceding row to redraw its bottom separator line (which is also the top line of the selected row)
if (([self isSelected]) && (selectedRowNumber > 0)) [tableView setNeedsDisplayInRect:[tableView rectOfRow:selectedRowNumber-1]];
}
此方法将(仅)绘制自己的底部分隔线。如果它是选定的行,它将绘制不使用默认颜色的行,但突出显示,它将告诉前一行重绘其分隔线,即与所选行的顶部分隔线相同。
为了使其工作,一旦选择移动,所选行上方的行需要重绘其底部分隔线。我通过在NSTableView委托中使用此方法来实现此目的:
// Tell the row above the row which is going to loose the selection to redraw its bottom separator line
- (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTableView
{
NSInteger selectedRowNumber = [aTableView selectedRow];
if (selectedRowNumber > 0) {
[aTableView setNeedsDisplayInRect:[aTableView rectOfRow:selectedRowNumber-1]];
}
return YES;
}
此委托方法告诉仍然选定的行上方的行重绘其分隔线。在选择更改之前立即调用它。