Reputation: 3489
MacOS 10.12+, Xcode 8+, Swift 3:
I'd like to programmatically customize the font and drawing of an NSTableView header. I know there are older questions about this, but I couldn't find anything that works today.
For example, I tried to subclass NSTableHeaderCell to set a custom font:
class MyHeaderCell: NSTableHeaderCell {
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
NSLog("MyHeaderCell is drawing")
font = NSFont.boldSystemFont(ofSize: 12)
super.drawInterior(withFrame: cellFrame, in: controlView)
}
}
And then use that subclass in my table view:
tableColumn.headerCell = MyHeaderCell()
I see the message "MyHeaderCell is drawing" in the console, but the font of the table header doesn't change.
Upvotes: 3
Views: 3798
Reputation: 2647
I was trying to change the header color with
tableColumn.headerCell.textColor = .secondaryLabelColor
but that didn't work. I ended up using the following:
tableColumn.headerCell.attributedStringValue = NSAttributedString(string: tableColumn.title, attributes: [.foregroundColor: NSColor.secondaryLabelColor])
Upvotes: 0
Reputation: 315
It has been some time since anyone has addressed this question. I've encountered the same very frustrating problem using Swift 5 and Xcode 12. Here is what I have learned using an nstableview approach that does not require subclassing.
at the beginning of the func tableView(_ myTable: NSTableView... add the following lines of code:
tableColumn?.headerCell.drawsBackground = true
tableColumn?.headerCell.backgroundColor = fill1Tint
This code changes the headerCell background color (and fill1Tint is some NSColor).
Then add:
let paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.center
within each tableColumn.identifier block, add an attributed text string such as:
let title: String = "Value"
tableColumn?.headerCell.attributedStringValue = NSAttributedString(string: title, attributes: [
NSAttributedString.Key.font: fontMedium,
NSAttributedString.Key.foregroundColor: text1Tint,
NSAttributedString.Key.paragraphStyle : paragraphStyle])
This code enables both a different background and centered, attributed text.
Upvotes: -1
Reputation: 3489
Thanks to comments from @HeinrichGiesen and @Willeke, I got it working. I'm posting it here in case it helps someone down the line. Note that my way of customizing the background color isn't that flexible. I'm really just tinting the default drawing. It's good enough for my purposes.
final class MyHeaderCell: NSTableHeaderCell {
// Customize background tint for header cell
override func draw(withFrame cellFrame: NSRect, in controlView: NSView) {
super.draw(withFrame: cellFrame, in: controlView)
NSColor(red: 0.9, green: 0.9, blue: 0.8, alpha: 0.2).set()
NSRectFillUsingOperation(cellFrame, .sourceOver)
}
// Customize text style/positioning for header cell
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
attributedStringValue = NSAttributedString(string: stringValue, attributes: [
NSFontAttributeName: NSFont.systemFont(ofSize: 11, weight: NSFontWeightSemibold),
NSForegroundColorAttributeName: NSColor(white: 0.4, alpha: 1),
])
let offsetFrame = NSOffsetRect(drawingRect(forBounds: cellFrame), 4, 0)
super.drawInterior(withFrame: offsetFrame, in: controlView)
}
}
Upvotes: 5