Skip to content

Instantly share code, notes, and snippets.

@marioaguzman
Last active February 1, 2026 13:51
Show Gist options
  • Select an option

  • Save marioaguzman/af67d5ce2e418a88986041d86f1fd220 to your computer and use it in GitHub Desktop.

Select an option

Save marioaguzman/af67d5ce2e418a88986041d86f1fd220 to your computer and use it in GitHub Desktop.
Creating NSTableView Gradient Header
import AppKit
/// Custom drawing of a Table's Header Row by darkening the background to a light gray rather than just being white.
class GradientTableHeaderCell: NSTableHeaderCell {
/// Light Mode Gradient
var backgroundFillGradient: NSGradient! {
NSGradient(colorsAndLocations:
(NSColor.secondarySystemFill.withAlphaComponent(0.55), 0.0), // Bottom
(NSColor.secondarySystemFill.withAlphaComponent(0.075), 1.0) // Top
)
}
/// Dark Mode Gradient
var darkBackgroundFillGradient: NSGradient! {
NSGradient(colorsAndLocations:
(NSColor.secondarySystemFill.withAlphaComponent(0.05), 0.0), // Bottom
(NSColor.secondarySystemFill.withAlphaComponent(0.55), 1.0) // Top
)
}
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
guard
let context = NSGraphicsContext.current?.cgContext else {
// If there's an issue, just draw the default and exit
super.drawInterior(withFrame: cellFrame, in: controlView)
return
}
let backgroundFillRect = CGRect(x: cellFrame.minX,
y: controlView.frame.minY,
width: cellFrame.width,
height: controlView.frame.height)
if controlView.window?.isMainWindow == true {
// Draw a gradient if the window is main
if controlView.isDarkAqua == true {
self.darkBackgroundFillGradient.draw(in: backgroundFillRect, angle: -90.0)
} else {
self.backgroundFillGradient.draw(in: backgroundFillRect, angle: -90.0)
}
} else {
// Otherwise draw a flat and muted background
if controlView.isDarkAqua == true {
NSColor.secondarySystemFill.withAlphaComponent(0.1).setFill()
} else {
NSColor.secondarySystemFill.withAlphaComponent(0.3).setFill()
}
context.fill(backgroundFillRect)
}
// Continue with default dividers, text, and sorting indicator drawing
super.drawInterior(withFrame: cellFrame, in: controlView)
}
}
extension NSView {
/// Returns `true` if the current view is being displayed in any variant of Dark Mode.
var isDarkAqua: Bool {
return
self.effectiveAppearance == NSAppearance(named: .darkAqua) ||
self.effectiveAppearance == NSAppearance(named: .vibrantDark)
}
}
// USAGE
// When instantiating, populating, and adding your columns to your table, use it like this:
let newColumn = NSTableColumn(identifier: "my_column_identifier")
newColumn.headerCell = GradientTableHeaderCell(textCell: "Column Title")
@marioaguzman
Copy link
Author

It should look like the Table Headers in this screenshot:
Screenshot 2026-02-01 at 12 01 53 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment