如何覆盖 NSTableHeaderView 的布局?
How do I override layout of NSTableHeaderView?
我正在尝试为我的 NSTableView 生成自定义 header。我想更改 header 文本的字体并删除边框和垂直分隔符。
我目前的顶部和底部header如下所示:
有人知道我该怎么做吗?
更新:应用修复后 header 现在看起来和我预期的一样:
您需要通过子classing NSTableHeaderCell
自己接管绘图,如下所示:
final class CustomTableHeaderCell : NSTableHeaderCell {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(textCell: String) {
super.init(textCell: textCell)
self.font = NSFont.boldSystemFontOfSize(20)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
// skip super.drawWithFrame(), since that is what draws borders
self.drawInteriorWithFrame(cellFrame, inView: controlView)
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView) {
let titleRect = self.titleRectForBounds(cellFrame)
self.attributedStringValue.drawInRect(titleRect)
}
}
如果您以编程方式设置 table,您可以这样做:
let col = NSTableColumn(identifier: id)
col.headerCell = CustomTableHeaderCell(textCell: title)
col.title = title
self.dataTableView.addTableColumn(col)
否则,您应该能够在 Interface Builder 中将 class 的名称设置为子class' 的名称。
一种方法,在您的 NSTableViewDelegate's
viewForTableColumn
-函数中:
if tableColumn!.identifier == "description" {
let cell = NSTableHeaderCell()
cell.title = "New Title"
cell.backgroundColor = NSColor.redColor()
cell.drawsBackground = true
cell.bordered = false
cell.font = NSFont(name: "Helvetica", size: 16)
tableColumn!.headerCell = cell
}
实际上,mprudhom 和 Pronto 的回答都对最终修复做出了很好的贡献。非常感谢你们。
我想我会 post 我的最终答案,这样任何后续的人都可以看到我是如何修复它的。
我不能单独使用 mprudhom 的代码,因为我的 table 只有一个 NSTableHeaderView 而没有 TableHeaderCells。幸运的是,Pronto 对此进行了救援:
class MyTable: NSTableView, NSTableViewDataSource, NSTableViewDelegate
{
override func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?
{
tableColumn!.headerCell = MyTableHeaderCell(textCell: tableColumn!.identifier)
}
}
我直接使用了 mprudhom 的 NSTableHeaderCell 代码:
final class MyTableHeaderCell : NSTableHeaderCell
{
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
override init(textCell: String)
{
super.init(textCell: textCell)
self.font = NSFont.boldSystemFontOfSize(14)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView)
{
//super.drawWithFrame(cellFrame, inView: controlView)//, since that is what draws borders
self.drawInteriorWithFrame(cellFrame, inView: controlView)
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView)
{
let titleRect = self.titleRectForBounds(cellFrame)
self.attributedStringValue.drawInRect(titleRect)
}
}
实现这两种方法后,我遇到了最后一个问题,即 NSTableHeaderView 按要求绘制时没有边框,但背景为灰色。所以我用这个方法覆盖了 NSTableHeaderView class:
class ForecastHeaderView : NSTableHeaderView
{
required init?(coder: NSCoder)
{
super.init(coder: coder)
}
override init(frame frameRect: NSRect)
{
super.init(frame: frameRect)
self.wantsLayer = true
}
override func drawLayer(layer: CALayer, inContext ctx: CGContext)
{
super.drawLayer(layer, inContext: ctx)
layer.backgroundColor = CGColorCreateGenericGray(1.0, 1.0)
}
}
以上答案也可以直接在viewDidLoad中使用
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableColumns.forEach { (column) in
column.headerCell.backgroundColor = NSColor.white
column.headerCell.drawsBackground = true
column.headerCell.isBordered = false
column.headerCell.attributedStringValue = NSAttributedString(string: column.title, attributes: [NSAttributedString.Key.font: NSFont.systemFont(ofSize: 13)])
}
}
在 macOS 11 中似乎有效的内容:
设置 NSTableHeaderCell 背景
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
tableColumn?.headerCell.drawsBackground = true
tableColumn?.headerCell.backgroundColor = .orange
...
将 IB 中的 NSTableView 样式设置为全宽
我正在尝试为我的 NSTableView 生成自定义 header。我想更改 header 文本的字体并删除边框和垂直分隔符。
我目前的顶部和底部header如下所示:
有人知道我该怎么做吗?
更新:应用修复后 header 现在看起来和我预期的一样:
您需要通过子classing NSTableHeaderCell
自己接管绘图,如下所示:
final class CustomTableHeaderCell : NSTableHeaderCell {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(textCell: String) {
super.init(textCell: textCell)
self.font = NSFont.boldSystemFontOfSize(20)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
// skip super.drawWithFrame(), since that is what draws borders
self.drawInteriorWithFrame(cellFrame, inView: controlView)
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView) {
let titleRect = self.titleRectForBounds(cellFrame)
self.attributedStringValue.drawInRect(titleRect)
}
}
如果您以编程方式设置 table,您可以这样做:
let col = NSTableColumn(identifier: id)
col.headerCell = CustomTableHeaderCell(textCell: title)
col.title = title
self.dataTableView.addTableColumn(col)
否则,您应该能够在 Interface Builder 中将 class 的名称设置为子class' 的名称。
一种方法,在您的 NSTableViewDelegate's
viewForTableColumn
-函数中:
if tableColumn!.identifier == "description" {
let cell = NSTableHeaderCell()
cell.title = "New Title"
cell.backgroundColor = NSColor.redColor()
cell.drawsBackground = true
cell.bordered = false
cell.font = NSFont(name: "Helvetica", size: 16)
tableColumn!.headerCell = cell
}
实际上,mprudhom 和 Pronto 的回答都对最终修复做出了很好的贡献。非常感谢你们。
我想我会 post 我的最终答案,这样任何后续的人都可以看到我是如何修复它的。
我不能单独使用 mprudhom 的代码,因为我的 table 只有一个 NSTableHeaderView 而没有 TableHeaderCells。幸运的是,Pronto 对此进行了救援:
class MyTable: NSTableView, NSTableViewDataSource, NSTableViewDelegate
{
override func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?
{
tableColumn!.headerCell = MyTableHeaderCell(textCell: tableColumn!.identifier)
}
}
我直接使用了 mprudhom 的 NSTableHeaderCell 代码:
final class MyTableHeaderCell : NSTableHeaderCell
{
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
override init(textCell: String)
{
super.init(textCell: textCell)
self.font = NSFont.boldSystemFontOfSize(14)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView)
{
//super.drawWithFrame(cellFrame, inView: controlView)//, since that is what draws borders
self.drawInteriorWithFrame(cellFrame, inView: controlView)
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView)
{
let titleRect = self.titleRectForBounds(cellFrame)
self.attributedStringValue.drawInRect(titleRect)
}
}
实现这两种方法后,我遇到了最后一个问题,即 NSTableHeaderView 按要求绘制时没有边框,但背景为灰色。所以我用这个方法覆盖了 NSTableHeaderView class:
class ForecastHeaderView : NSTableHeaderView
{
required init?(coder: NSCoder)
{
super.init(coder: coder)
}
override init(frame frameRect: NSRect)
{
super.init(frame: frameRect)
self.wantsLayer = true
}
override func drawLayer(layer: CALayer, inContext ctx: CGContext)
{
super.drawLayer(layer, inContext: ctx)
layer.backgroundColor = CGColorCreateGenericGray(1.0, 1.0)
}
}
以上答案也可以直接在viewDidLoad中使用
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableColumns.forEach { (column) in
column.headerCell.backgroundColor = NSColor.white
column.headerCell.drawsBackground = true
column.headerCell.isBordered = false
column.headerCell.attributedStringValue = NSAttributedString(string: column.title, attributes: [NSAttributedString.Key.font: NSFont.systemFont(ofSize: 13)])
}
}
在 macOS 11 中似乎有效的内容:
设置 NSTableHeaderCell 背景
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { tableColumn?.headerCell.drawsBackground = true tableColumn?.headerCell.backgroundColor = .orange ...
将 IB 中的 NSTableView 样式设置为全宽