获取与另一个颜色合成所需的颜色,以快速获得目标颜色



我使用NSTableViewNSTableCellView(s)中绘制一些信息。我想将NSTableView的背景颜色设置为某个值,将NSTableCellView's背景颜色设置为另一个值,而与所用颜色的 alpha 分量无关。问题是,如果我将 alpha 分量 0.3 的背景颜色设置为NSTableCellView,我们会看到NSTableView的背景色,然后颜色不是我设置的颜色。

我看到两个选项可以解决此问题:

  1. 绘制NSTableView的背景色,而无需在NSTableCellView(s)使用的矩形下绘制。
  2. 使用色彩理论和 CoreGraphics 来计算新颜色。

我已经解决了一些选项 1,但没有得到任何结果。我现在正在研究更多选项2。

例如,如果我有两种颜色:

let tableViewBackgroundColor = NSColor(calibratedRed: 48/255, green: 47/255, blue: 46/255, alpha: 1)
let tableViewCellBackgroundColor = NSColor(calibratedRed: 42/255, green: 41/255, blue: 40/255, alpha: 1)

我希望将生成的颜色应用于NSTableCellView背景:

let targetColor = tableViewCellBackgroundColor.withAplphaComponent(0.3)

即使颜色:

let tableViewBackgroundColorWithAlpha = tableViewBackgroundColor.withAlphaComponent(0.3)

应用于 NSTableView 的背景。

我正在寻找NSColor的扩展(CGColor可以工作),如下所示:

extension NSColor {
///
/// Return the color that needs to be composed with the color parameter 
/// in order to result in the current (self) color.
///
func composedColor(with color: NSColor) -> NSColor
}

可以这样使用:

let color = targetColor.composedColor(with: 
tableViewBackgroundColorWithAlpha)

知道吗?

回答我自己的问题,这个问题的解决方案最终是避免使用表格视图单元格绘制零件(问题的选项 1)。我从与 SwiftNSTableViews绘制自定义交替行背景中汲取灵感,以实现最终解决方案。

它基本上涉及覆盖NSTableView的方法func drawBackground(inClipRect clipRect: NSRect),但避免绘制存在单元格的表格背景部分。

这是解决方案:

override func drawBackground(inClipRect clipRect: NSRect) {
super.drawBackground(inClipRect: clipRect)
drawTopBackground(inClipRect: clipRect)
drawBottomBackground(inClipRect: clipRect)
}
private func drawTopBackground(inClipRect clipRect: NSRect) {
guard clipRect.origin.y < 0 else { return }
let rectHeight = rowHeight + intercellSpacing.height
let minY = NSMinY(clipRect)
var row = 0
currentBackgroundColor.setFill()
while true {
let rowRect = NSRect(x: 0, y: (rectHeight * CGFloat(row) - rectHeight), width: NSMaxX(clipRect), height: rectHeight)
if self.rows(in: rowRect).isEmpty {
rowRect.fill()
}
if rowRect.origin.y < minY { break }
row -= 1
}
}
private func drawBottomBackground(inClipRect clipRect: NSRect) {
let rectHeight = rowHeight + intercellSpacing.height
let maxY = NSMaxY(clipRect)
var row = rows(in: clipRect).location
currentBackgroundColor.setFill()
while true {
let rowRect = NSRect(
x: 0,
y: (rectHeight * CGFloat(row)),
width: NSMaxX(clipRect),
height: rectHeight)
if self.rows(in: rowRect).isEmpty {
rowRect.fill()
}
if rowRect.origin.y > maxY { break }
row += 1
}
}

最新更新