Skip to content

Instantly share code, notes, and snippets.

@ollieatkinson
Last active June 14, 2022 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ollieatkinson/c3b82dcaf8215e842f3b85c7df7ed774 to your computer and use it in GitHub Desktop.
Save ollieatkinson/c3b82dcaf8215e842f3b85c7df7ed774 to your computer and use it in GitHub Desktop.
A Simple UIView Wrapper for CAGradientLayer
/// A Simple UIView Wrapper for CAGradientLayer. It is a plain UIView whose layer
/// is a CAGradientLayer. It is useful if using a view is more convenient than using a layer, e.g.
/// because you want to use autoresizing masks.
class GradientView: UIView {
/// The direction to draw the gradient, in a single point coordinate space.
enum Direction {
/// Draw the gradient from top to bottom.
case vertical
/// Draw the gradient from left to right.
case horizontal
// Draw the gradient in a custom direction providing the start and end points.
case custom(start: CGPoint, end: CGPoint)
/// The start point of the gradient when drawn.
var startPoint: CGPoint {
switch self {
case .vertical:
return CGPoint(x: 0.5, y: 0)
case .horizontal:
return CGPoint(x: 0, y: 0.5)
case .custom(start: let start, end: _):
return start
}
}
/// The end point of the gradient when drawn.
var endPoint: CGPoint {
switch self {
case .vertical:
return CGPoint(x: 0.5, y: 1)
case .horizontal:
return CGPoint(x: 1, y: 0.5)
case .custom(start: _, end: let end):
return end
}
}
}
/// The CAGradientLayer instance containing the gradient information to play.
var gradientLayer: CAGradientLayer {
//swiftlint:disable force_cast
return layer as! CAGradientLayer
//swiftlint:enable force_cast
}
// Override UIView property. The class used to create the layer for instances of this class.
override static var layerClass: AnyClass {
return CAGradientLayer.self
}
/// An array of UIColor objects defining the color of each gradient stop. Animatable.
///
/// Defaults to nil.
var colors: [UIColor]? {
didSet {
gradientLayer.colors = colors?.map { $0.cgColor }
}
}
/// An optional array of Double objects defining the location of each gradient stop. Animatable.
///
/// The gradient stops are specified as values between 0 and 1.
/// The values must be monotonically increasing. If nil, the stops are spread uniformly across the range.
///
/// Defaults to nil.
var locations: [Double]? {
didSet {
gradientLayer.locations = locations?.map(NSNumber.init(value:))
}
}
/// The direction to draw the gradient. Animatable.
///
/// Defaults to vertical:
/// - startPoint: (0.5, 0.0)
/// - endPoint: (0.5, 1.0)
var direction: Direction {
didSet {
gradientLayer.startPoint = direction.startPoint
gradientLayer.endPoint = direction.endPoint
}
}
/// Initialise with default values calling didSet to update the underlying gradient layer in the process.
override init(frame: CGRect) {
self.colors = nil
self.direction = .vertical
self.locations = nil
super.init(frame: frame)
}
/// Not yet implemented.
required init?(coder aDecoder: NSCoder) {
fatalError("not implemented")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment