gpt4 book ai didi

objective-c - 像 iTunes 11 一样绘制 NSTableView 交替行

转载 作者:太空狗 更新时间:2023-10-30 03:28:17 26 4
gpt4 key购买 nike

我知道在 SO 上还有其他关于更改交替行颜色的问题。这很容易,这不是我想做的。

我想在基于 View 的 NSTableView 中绘制自定义交替颜色的行,看起来像 iTunes 11 中的行(行的顶部和底部有小边框,如屏幕截图所示):

iTunes 11 screenshot

注意:

我知道我可以子类化 NSTableRowView 并在那里进行自定义绘图。但是,这不是一个可接受的答案,因为自定义行将仅用于表中具有数据的行。换句话说,如果表格只有 5 行,那 5 行将使用我的自定义 NSTableRowView 类,但表格其余部分(为空)中的其余“行”将使用标准交替颜色。在这种情况下,前 5 行将显示挡板,而其余的则不会。不好。

那么,我如何破解 NSTableView 来为填充行和空行绘制这些样式交替的行?

最佳答案

正如您所说,“小边框”实际上可以通过我们的一些作弊轻松完成。因为,如果你仔细观察,每个单元格的顶部是比深色交替行略浅的蓝色,每个单元格的底部是深灰色,你可以子类化 NSTableView,然后重写 - (void) drawRow:(NSInteger)row clipRect:(NSRect)clipRect:

- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
{
//Use the drawing code from http://stackoverflow.com/a/5101923/945847, but change the colors to
//look like iTunes's alternating rows.
NSRect cellBounds = [self rectOfRow:row];
NSColor *color = (row % 2) ? [NSColor colorWithCalibratedWhite:0.975 alpha:1.000] : [NSColor colorWithCalibratedRed:0.932 green:0.946 blue:0.960 alpha:1.000];
[color setFill];
NSRectFill(cellBounds);

/* Slightly dark gray color */
[[NSColor colorWithCalibratedWhite:0.912 alpha:1.000] set];
/* Get the current graphics context */
CGContextRef currentContext = [[NSGraphicsContext currentContext]graphicsPort];
/*Draw a one pixel line of the slightly lighter blue color */
CGContextSetLineWidth(currentContext,1.0f);
/* Start the line at the top of our cell*/
CGContextMoveToPoint(currentContext,0.0f, NSMaxY(cellBounds));
/* End the line at the edge of our tableview, for multi-columns, this will actually be overkill*/
CGContextAddLineToPoint(currentContext,NSMaxX(cellBounds), NSMaxY(cellBounds));
/* Use the context's current color to draw the line */
CGContextStrokePath(currentContext);

/* Slightly lighter blue color */
[[NSColor colorWithCalibratedRed:0.961 green:0.970 blue:0.985 alpha:1.000] set];
CGContextSetLineWidth(currentContext,1.0f);
CGContextMoveToPoint(currentContext,0.0f,1.0f);
CGContextAddLineToPoint(currentContext,NSMaxX(self.bounds), 1.0f);
CGContextStrokePath(currentContext);

[super drawRow:row clipRect:clipRect];
}

在一个快速的小表格 View 中完成后,看起来像这样: Nice Bezeling!

但是tableview的顶部和底部怎么办呢?毕竟,它们仍然是丑陋的白色或默认的交替行颜色。好吧,正如 Apple 透露的那样(在题为“有趣的 View Based NSTableView, Basic To Advanced”的演讲中),您可以覆盖 -(void)drawBackgroundInClipRect:(NSRect)clipRect 并做一些数学运算来绘制 tableview 的背景像额外的行。快速实现看起来像这样:

-(void)drawBackgroundInClipRect:(NSRect)clipRect
{
// The super class implementation obviously does something more
// than just drawing the striped background, because
// if you leave this out it looks funny
[super drawBackgroundInClipRect:clipRect];

CGFloat yStart = 0;
NSInteger rowIndex = -1;

if (clipRect.origin.y < 0) {
while (yStart > NSMinY(clipRect)) {
CGFloat yRowTop = yStart - self.rowHeight;

NSRect rowFrame = NSMakeRect(0, yRowTop, clipRect.size.width, self.rowHeight);
NSUInteger colorIndex = rowIndex % self.colors.count;
NSColor *color = [self.colors objectAtIndex:colorIndex];
[color set];
NSRectFill(rowFrame);

/* Slightly dark gray color */
[[NSColor colorWithCalibratedWhite:0.912 alpha:1.000] set];
/* Get the current graphics context */
CGContextRef currentContext = [[NSGraphicsContext currentContext]graphicsPort];
/*Draw a one pixel line of the slightly lighter blue color */
CGContextSetLineWidth(currentContext,1.0f);
/* Start the line at the top of our cell*/
CGContextMoveToPoint(currentContext,0.0f, yRowTop + self.rowHeight - 1);
/* End the line at the edge of our tableview, for multi-columns, this will actually be overkill*/
CGContextAddLineToPoint(currentContext,NSMaxX(clipRect), yRowTop + self.rowHeight - 1);
/* Use the context's current color to draw the line */
CGContextStrokePath(currentContext);

/* Slightly lighter blue color */
[[NSColor colorWithCalibratedRed:0.961 green:0.970 blue:0.985 alpha:1.000] set];
CGContextSetLineWidth(currentContext,1.0f);
CGContextMoveToPoint(currentContext,0.0f,yRowTop);
CGContextAddLineToPoint(currentContext,NSMaxX(clipRect), yRowTop);
CGContextStrokePath(currentContext);

yStart -= self.rowHeight;
rowIndex--;
}
}
}

但是,这会在 tableview 的底部留下同样难看的空白白色!因此,我们还必须覆盖 -(void)drawGridInClipRect:(NSRect)clipRect。另一个快速实现如下所示:

-(void)drawGridInClipRect:(NSRect)clipRect {
[super drawGridInClipRect:clipRect];

NSUInteger numberOfRows = self.numberOfRows;
CGFloat yStart = 0;
if (numberOfRows > 0) {
yStart = NSMaxY([self rectOfRow:numberOfRows - 1]);
}
NSInteger rowIndex = numberOfRows + 1;

while (yStart < NSMaxY(clipRect)) {
CGFloat yRowTop = yStart - self.rowHeight;

NSRect rowFrame = NSMakeRect(0, yRowTop, clipRect.size.width, self.rowHeight);
NSUInteger colorIndex = rowIndex % self.colors.count;
NSColor *color = [self.colors objectAtIndex:colorIndex];
[color set];
NSRectFill(rowFrame);

/* Slightly dark gray color */
[[NSColor colorWithCalibratedWhite:0.912 alpha:1.000] set];
/* Get the current graphics context */
CGContextRef currentContext = [[NSGraphicsContext currentContext]graphicsPort];
/*Draw a one pixel line of the slightly lighter blue color */
CGContextSetLineWidth(currentContext,1.0f);
/* Start the line at the top of our cell*/
CGContextMoveToPoint(currentContext,0.0f, yRowTop - self.rowHeight);
/* End the line at the edge of our tableview, for multi-columns, this will actually be overkill*/
CGContextAddLineToPoint(currentContext,NSMaxX(clipRect), yRowTop - self.rowHeight);
/* Use the context's current color to draw the line */
CGContextStrokePath(currentContext);

/* Slightly lighter blue color */
[[NSColor colorWithCalibratedRed:0.961 green:0.970 blue:0.985 alpha:1.000] set];
CGContextSetLineWidth(currentContext,1.0f);
CGContextMoveToPoint(currentContext,0.0f,yRowTop);
CGContextAddLineToPoint(currentContext,NSMaxX(self.bounds), yRowTop);
CGContextStrokePath(currentContext);

yStart += self.rowHeight;
rowIndex++;
}
}

当一切都说完了之后,我们在 clipview 的顶部和底部得到了漂亮的小假 TableView 单元格行,看起来有点像这样:

enter image description here

可以找到完整的子类 here .

关于objective-c - 像 iTunes 11 一样绘制 NSTableView 交替行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14178370/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com