// // GradientView.swift // App // // Created by James Magahern on 8/14/20. // import UIKit class GradientView: UIImageView { enum Direction { case horizontal case vertical } var direction: Direction = .horizontal { didSet { image = nil; setNeedsLayout() } } var colors: [UIColor] = [] { didSet { image = nil; setNeedsLayout() } } private var generatedImageSize: CGSize? convenience init(direction: Direction, colors: [UIColor]) { self.init(image: nil) self.direction = direction self.colors = colors registerForTraitChanges([UITraitUserInterfaceStyle.self]) { [weak self] (traitEnvironment: Self, previousTraitCollection) in self?.image = nil self?.setNeedsLayout() } } private func gradientImage(forSize size: CGSize) -> UIImage? { guard size.width > .leastNonzeroMagnitude && size.height > .leastNonzeroMagnitude else { return nil } var image: UIImage? = nil UIGraphicsBeginImageContext(size) if let context = UIGraphicsGetCurrentContext() { let gradientColorsArray = self.colors.map { $0.cgColor } if let gradient = CGGradient(colorsSpace: nil, colors: gradientColorsArray as CFArray, locations: nil) { if direction == .horizontal { context.drawLinearGradient(gradient, start: .zero, end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions()) } else if direction == .vertical { context.drawLinearGradient(gradient, start: CGPoint(x: size.width / 2, y: 0), end: CGPoint(x: size.width / 2, y: size.height), options: CGGradientDrawingOptions()) } } image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext(); } return image } override func layoutSubviews() { super.layoutSubviews() var needsNewImage: Bool = image == nil if let generatedImageSize = generatedImageSize { if generatedImageSize != bounds.size { needsNewImage = true } } else { needsNewImage = true } if needsNewImage { image = gradientImage(forSize: bounds.size) generatedImageSize = bounds.size } } }