A common design element in apps is a gradient, often as the background of a view. This post walks through the implementation of a GradientBackgroundView
class that:
- Automatically redraws when colors and drawing points are assigned
- Is configurable in a Storyboard and in code
- Automatically and correctly handles rotation and bounds changes
Here are the steps to implement a UIView with a gradient background:
- Override layerClass To Add A CAGradientLayer
- @IBDesignable With Gradient Background
- Add Gradient Colors With cgColorGradient
Override layerClass To Add A CAGradientLayer
Some examples and implementations of gradient UIView
backgrounds in Swift insert a CAGradientLayer
at index 0 to a view's layer
. This implementation contains some drawbacks, including the need to manage the CAGradientLayer
's frame during rotation and resizing.
A better approach is to override the layerClass
variable, explicitly setting the base layer class to CAGradientLayer
. With this implementation, UIView
will instantiate layer
as an instance of CAGradientLayer
and will manage the layer for us, including rotation and resizing.
class GradientBackgroundView: UIView {
// Enables more convenient access to layer
var gradientLayer: CAGradientLayer {
return layer as! CAGradientLayer
}
override open class var layerClass: AnyClass {
return CAGradientLayer.classForCoder()
}
}
@IBDesignable With Gradient Background
To make GradientBackgroundView
configurable we want to expose a number of configuration options. Each is an @IBInspectable
variable to enable modification in a Storyboard. By using didSet
to update the layer properties, the layer will automatically redraw when necessary and display correctly as a gradient in a Storyboard.
@IBDesignable class GradientBackgroundView: UIView {
// implement cgcolorgradient in the next section
@IBInspectable var startColor: UIColor? {
didSet { gradientLayer.colors = cgColorGradient }
}
@IBInspectable var endColor: UIColor? {
didSet { gradientLayer.colors = cgColorGradient }
}
@IBInspectable var startPoint: CGPoint = CGPoint(x: 0.0, y: 0.0) {
didSet { gradientLayer.startPoint = startPoint }
}
@IBInspectable var endPoint: CGPoint = CGPoint(x: 1.0, y: 1.0) {
didSet { gradientLayer.endPoint = endPoint }
}
// existing code
}
Add Gradient Colors With cgColorGradient
The final step is to implement cgColorGradient
, a convenience variable that contains logic needed to determine if the gradient color configuration is valid. One way to implement this is an internal var
of GradientBackgroundView
.
extension GradientBackgroundView {
// For this implementation, both colors are required to display
// a gradient. You may want to extend cgColorGradient to support
// other use cases, like gradients with three or more colors.
internal var cgColorGradient: [CGColor]? {
guard let startColor = startColor, let endColor = endColor else {
return nil
}
return [startColor.cgColor, endColor.cgColor]
}
}
UIView With A Gradient Background In Swift
That's it! With the @IBDesignable
GradientBackgroundView
, a UIView
subclass, you can add views with gradient backgrounds to your iOS apps.