Files
Attractor/App/Common UI/GradientView.swift
2024-07-29 19:21:51 -07:00

79 lines
2.4 KiB
Swift

//
// 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
}
}
}