I\'m using the \"Alternating Rows\" option in Interface Builder to get alternating row colors on an NSTableView. Is there any way to change the colors of the alternating row
Swift 4+ version of 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
}
}
}