我正在使用Interface Builder中的“Alternating Rows”选项在NSTableView上获取交替的行颜色。有没有办法改变交替行的颜色?
答案 0 :(得分:7)
如果您想使用未记录的方式,请制作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
答案 1 :(得分:7)
找到了更好的方法here。该方法会覆盖NSTableView子类中的highlightSelectionInClipRect:方法,因此您可以使用所需的任何颜色来替换交替行。它不像使用NSColor类别那样苛刻,它只会影响您选择的表格视图。
答案 2 :(得分:4)
我将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];
}
它似乎有用,但它很简单,我想知道我是否遗漏了什么。
答案 3 :(得分:3)
我想要一个像常规NSTableView
一样工作的解决方案,包括对弹性滚动等的支持,所以我创建了一个NSTableView
子类,其NSColor*
属性称为{{1}然后覆盖alternateBackgroundColor
方法,如下所示:
-drawBackgroundColorInClipRect:
答案 4 :(得分:3)
我不确定最近是如何添加的,或者它是否像您需要的那样灵活,但我注意到您可以在Xcode 4.6中的Interface Builder中指定“交替”行(可能更早)。
NSTableView
或NSOutlineView
Highlight Alternating Rows
复选框。
答案 5 :(得分:1)
没有可设置的属性,但您可以响应委托方法-tableView:willDisplayCell:forTableColumn:row:
并根据行号的均匀度设置单元格的背景颜色。
答案 6 :(得分:1)
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(numberOfRows-1)
virtualRowOrigin = finalRect.origin.y + finalRect.size.height
}
repeat {
if virtualRowNumber % 2 != 0 {
// This is an alternate row
let virtualRowRect = NSRect(x: clipRect.origin.x, y: virtualRowOrigin, width: clipRect.size.width, height: thisRowHeight)
NSRectFill(virtualRowRect)
}
virtualRowNumber++
virtualRowOrigin += thisRowHeight
} while virtualRowOrigin < clipRect.origin.y + clipRect.size.height
// Draw fake rows above the table's first row
virtualRowOrigin = -1 * thisRowHeight
virtualRowNumber = -1
repeat {
if abs(virtualRowNumber) % 2 != 0 {
// This is an alternate row
let virtualRowRect = NSRect(x: clipRect.origin.x, y: virtualRowOrigin, width: clipRect.size.width, height: thisRowHeight)
NSRectFill(virtualRowRect)
}
virtualRowNumber--
virtualRowOrigin -= thisRowHeight
} while virtualRowOrigin + thisRowHeight > clipRect.origin.y
}
}
}
}
答案 7 :(得分:1)
Swift 4 + 版本的AlternateRealist's answer:
public class AlternateBgColorTableView: NSTableView {
var alternateBackgroundColor: NSColor? = .red
override public func drawBackground(inClipRect clipRect: NSRect) {
// If we didn't set the alternate color, fall back to the default behavior
guard let alternateBackgroundColor = alternateBackgroundColor else {
super.drawBackground(inClipRect: clipRect)
return
}
// Fill in the background color
backgroundColor.set()
clipRect.fill()
// Check if we should be drawing alternating colored rows
if usesAlternatingRowBackgroundColors {
// Set the alternating background color
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.height
let rowsToDraw = rows(in: checkRect)
var currentRow = rowsToDraw.location
repeat {
if currentRow % 2 != 0 {
// This is an alternate row
var rowRect = rect(ofRow: currentRow)
rowRect.origin.x = clipRect.origin.x
rowRect.size.width = clipRect.width
rowRect.fill()
}
currentRow += 1
} while currentRow < rowsToDraw.location + rowsToDraw.length
// Figure out the height of "off the table" rows
var thisRowHeight = rowHeight
if gridStyleMask.contains(.solidHorizontalGridLineMask) || gridStyleMask.contains(.dashedHorizontalGridLineMask) {
thisRowHeight += 2 // Compensate for a grid
}
// Draw fake rows below the table's last row
var virtualRowOrigin: CGFloat = 0
var virtualRowNumber = numberOfRows
if numberOfRows > 0 {
let finalRect = rect(ofRow: numberOfRows - 1)
virtualRowOrigin = finalRect.origin.y + finalRect.height
}
repeat {
if virtualRowNumber % 2 != 0 {
// This is an alternate row
let virtualRowRect = NSRect(x: clipRect.origin.x, y: virtualRowOrigin, width: clipRect.width, height: thisRowHeight)
virtualRowRect.fill()
}
virtualRowNumber += 1
virtualRowOrigin += thisRowHeight
} while virtualRowOrigin < clipRect.origin.y + clipRect.size.height
// Draw fake rows above the table's first row
virtualRowOrigin = -1 * thisRowHeight
virtualRowNumber = -1
repeat {
if abs(virtualRowNumber) % 2 != 0 {
// This is an alternate row
let virtualRowRect = NSRect(x: clipRect.origin.x, y: virtualRowOrigin, width: clipRect.width, height: thisRowHeight)
virtualRowRect.fill()
}
virtualRowNumber -= 1
virtualRowOrigin -= thisRowHeight
} while virtualRowOrigin + thisRowHeight > clipRect.origin.y
}
}
}
答案 8 :(得分:0)
如果您希望将自定义颜色设置为与每行数据配对,那么由于上面的帖子,我发现了这种方法,并且该解决方案还致力于实现自定义替代行颜色(空行):
创建NSTableView的子类:
ColoredRowTableView.h
@protocol ColoredRowTableViewDelegate <NSTableViewDelegate>
-(NSColor *)colorForRow:(NSInteger)row;
@end
@interface ColoredRowTableView : NSTableView
@end
在ColoredRowTableView.m中
- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
{
if (row == [self selectedRow])
{
[super drawRow:row clipRect:clipRect];
return;
}
NSColor *color = [(id<ColoredRowTableViewDelegate>)[self delegate] colorForRow:row];
[color setFill];
NSRectFill([self rectOfRow:row]);
[super drawRow:row clipRect:clipRect];
}
然后在您的表视图委托中:
#import "ColoredRowTableView.h"
@interface MyTableViewDelegate : NSViewController <ColoredRowTableViewDelegate>
// instead of <NSTableViewDelegate>
在您的委托中实现colorForRow:方法。如果目标仅是提供备用行,则可以返回基于行号的颜色(如果是偶数或奇数)。 同样不要忘记在界面构建器中将表视图的类更改为ColoredRowTableView