This post walks through the implementation for GradientButton
, an NSButton
subclass. GradientButton
is a button with text on top of a gradient background.
Configure Properties
To draw a gradient using NSGradient
, specify at minimum the colors of the gradient and the gradient draw angle. For GradientButton
, the colors and angle are implemented as configurable properties:
@IBDesignable class GradientButton: NSButton {
@IBInspectable var gradientInitialColor: NSColor = .white
@IBInspectable var gradientFinalColor: NSColor = .black
@IBInspectable var gradientAngle: CGFloat = 270.0
}
Override draw(:)
Prepare to add custom draw code by overriding draw(:)
:
// inside of GradientButton
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
// ...
Draw Gradient
Use NSGradient
to draw the gradient. In order to make the button interactive, the gradient angle is changing when the button is in the highlighted state. In other words, the gradient will change when the user clicks on the button.
// inside of draw(_ dirtyRect:)
// Configure the gradient
var gradientAngle = self.gradientAngle
if isHighlighted { gradientAngle += 45 }
let gradient = NSGradient(colors: [
gradientInitialColor, gradientFinalColor
])
// Draw the gradient
gradient?.draw(in: bounds, angle: gradientAngle)
// ...
NSButton With A Gradient Background
That's it! With GradientButton
you can implement an NSButton
with a gradient background. The provided implementation of GradientButton
results in the following:
Complete Implementation
@IBDesignable class GradientButton: NSButton {
@IBInspectable var gradientInitialColor: NSColor = .white
@IBInspectable var gradientFinalColor: NSColor = .black
@IBInspectable var gradientAngle: CGFloat = 270.0
override func draw(_ dirtyRect: NSRect) {
// Configure the gradient
var gradientAngle = self.gradientAngle
if isHighlighted { gradientAngle += 45 }
let gradient = NSGradient(colors: [
gradientInitialColor, gradientFinalColor
])
// Draw the gradient
gradient?.draw(in: bounds, angle: gradientAngle)
super.draw(dirtyRect)
}
}