更改NSTableView备用行颜色
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更改NSTableView备用行颜色相关的知识,希望对你有一定的参考价值。
我正在使用Interface Builder中的“Alternating Rows”选项在NSTableView上获取交替的行颜色。有没有办法改变交替行的颜色?
如果你想使用一种未记录的方式,请制作一个NSColor
类别并覆盖_blueAlternatingRowColor
,如下所示:
@implementation NSColor (ColorChangingFun)
+(NSColor*)_blueAlternatingRowColor
return [NSColor redColor];
@end
或者要更改两种颜色,请覆盖controlAlternatingRowBackgroundColors
以返回您想要交替的颜色数组。
@implementation NSColor (ColorChangingFun)
+(NSArray*)controlAlternatingRowBackgroundColors
return [NSArray arrayWithObjects:[NSColor redColor], [NSColor greenColor], nil];
@end
找到了更好的方法来做here。该方法会覆盖NSTableView子类中的highlightSelectionInClipRect:方法,因此您可以使用所需的任何颜色来替换交替行。它不像使用NSColor类别那样hackish,它只影响你选择的表视图。
我将NSTableView子类化并实现了drawRow:clipRect:就像这样......
- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
NSColor *color = (row % 2) ? [NSColor redColor] : [NSColor whiteColor];
[color setFill];
NSRectFill([self rectOfRow:row]);
[super drawRow:row clipRect:clipRect];
它似乎有效,但它很简单,我想知道我是否遗漏了一些东西。
我想要一个像常规NSTableView
一样工作的解决方案,包括支持弹性滚动等等,所以我创建了一个NSTableView
子类,它有一个名为NSColor*
的alternateBackgroundColor
属性,然后像这样覆盖-drawBackgroundColorInClipRect:
方法:
- (void) drawBackgroundInClipRect:(NSRect)clipRect
if([self alternateBackgroundColor] == nil)
// If we didn't set the alternate colour, fall back to the default behaviour
[super drawBackgroundInClipRect:clipRect];
else
// Fill in the background colour
[[self backgroundColor] set];
NSRectFill(clipRect);
// Check if we should be drawing alternating coloured rows
if([self alternateBackgroundColor] && [self usesAlternatingRowBackgroundColors])
// Set the alternating background colour
[[self alternateBackgroundColor] set];
// Go through all of the intersected rows and draw their rects
NSRect checkRect = [self bounds];
checkRect.origin.y = clipRect.origin.y;
checkRect.size.height = clipRect.size.height;
NSRange rowsToDraw = [self rowsInRect:checkRect];
NSUInteger curRow = rowsToDraw.location;
while(curRow < rowsToDraw.location + rowsToDraw.length)
if(curRow % 2 != 0)
// This is an alternate row
NSRect rowRect = [self rectOfRow:curRow];
rowRect.origin.x = clipRect.origin.x;
rowRect.size.width = clipRect.size.width;
NSRectFill(rowRect);
curRow++;
// Figure out the height of "off the table" rows
CGFloat rowHeight = [self rowHeight];
if( ([self gridStyleMask] & NSTableViewSolidHorizontalGridLineMask) == NSTableViewSolidHorizontalGridLineMask
|| ([self gridStyleMask] & NSTableViewDashedHorizontalGridLineMask) == NSTableViewDashedHorizontalGridLineMask)
rowHeight += 2.0f; // Compensate for a grid
// Draw fake rows below the table's last row
CGFloat virtualRowOrigin = 0.0f;
NSInteger virtualRowNumber = [self numberOfRows];
if([self numberOfRows] > 0)
NSRect finalRect = [self rectOfRow:[self numberOfRows]-1];
virtualRowOrigin = finalRect.origin.y + finalRect.size.height;
while(virtualRowOrigin < clipRect.origin.y + clipRect.size.height)
if(virtualRowNumber % 2 != 0)
// This is an alternate row
NSRect virtualRowRect = NSMakeRect(clipRect.origin.x,virtualRowOrigin,clipRect.size.width,rowHeight);
NSRectFill(virtualRowRect);
virtualRowNumber++;
virtualRowOrigin += rowHeight;
// Draw fake rows above the table's first row
virtualRowOrigin = -1 * rowHeight;
virtualRowNumber = -1;
while(virtualRowOrigin + rowHeight > clipRect.origin.y)
if(abs(virtualRowNumber) % 2 != 0)
// This is an alternate row
NSRect virtualRowRect = NSMakeRect(clipRect.origin.x,virtualRowOrigin,clipRect.size.width,rowHeight);
NSRectFill(virtualRowRect);
virtualRowNumber--;
virtualRowOrigin -= rowHeight;
我不确定最近这是如何添加的,或者它是否像您需要的那样灵活,但我注意到您可以在Xcode 4.6中(可能更早)在Interface Builder中指定“交替”行。
- 在Xcode中打开你的笔尖并选择你的
NSTableView
或NSOutlineView
- 在“实用程序”窗格中显示“属性”检查器(⎇⌘4)
- 注意
Highlight Alternating Rows
复选框。
没有可设置的属性,但是您可以响应委托方法-tableView:willDisplayCell:forTableColumn:row:
并根据行号的均匀度设置单元格的背景颜色。
Nate Thorn的answer对我来说非常合适。
在这里,为Swift重构:
import Foundation
import Cocoa
import AppKit
public class SubclassedTableView : NSTableView
private func
alternateBackgroundColor() -> NSColor?
return NSColor.redColor() // Return any color you like
public override func
drawBackgroundInClipRect(clipRect: NSRect)
if alternateBackgroundColor() == nil
// If we didn't set the alternate colour, fall back to the default behaviour
super.drawBackgroundInClipRect(clipRect)
else
// Fill in the background colour
self.backgroundColor.set()
NSRectFill(clipRect)
// Check if we should be drawing alternating coloured rows
if usesAlternatingRowBackgroundColors
// Set the alternating background colour
alternateBackgroundColor()!.set()
// Go through all of the intersected rows and draw their rects
var checkRect = bounds
checkRect.origin.y = clipRect.origin.y
checkRect.size.height = clipRect.size.height
let rowsToDraw = rowsInRect(checkRect)
var curRow = rowsToDraw.location
repeat
if curRow % 2 != 0
// This is an alternate row
var rowRect = rectOfRow(curRow)
rowRect.origin.x = clipRect.origin.x
rowRect.size.width = clipRect.size.width
NSRectFill(rowRect)
curRow++
while curRow < rowsToDraw.location + rowsToDraw.length
// Figure out the height of "off the table" rows
var thisRowHeight = rowHeight
if gridStyleMask.contains(NSTableViewGridLineStyle.SolidHorizontalGridLineMask)
|| gridStyleMask.contains(NSTableViewGridLineStyle.DashedHorizontalGridLineMask)
thisRowHeight += 2.0 // Compensate for a grid
// Draw fake rows below the table's last row
var virtualRowOrigin = 0.0 as CGFloat
var virtualRowNumber = numberOfRows
if numberOfRows > 0
let finalRect = rectOfRow(numberOfR以上是关于更改NSTableView备用行颜色的主要内容,如果未能解决你的问题,请参考以下文章
在 NSCollectionViewItem 实例中更新 NSTableView