You can do this with "Dynamic Providers"
For example, in your custom gradient view class:
var startGradientColorDarkMode: UIColor = .white
var startGradientColorLightMode: UIColor = .black
lazy var myStartColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
if traitCollection.userInterfaceStyle == .dark {
return self.startGradientColorDarkMode
} else {
return self.startGradientColorLightMode
}
}
You can then use myStartColor.cgColor in your gradient colors array.
Here is a complete example:
class MyGradientView: UIView {
// default Dark mode - white to orange
var startGradientColorDarkMode: UIColor = .white
{
didSet {
self.setNeedsLayout()
}
}
var endGradientColorDarkMode: UIColor = .orange
{
didSet {
self.setNeedsLayout()
}
}
// default Light mode - black to blue
var startGradientColorLightMode: UIColor = .black
{
didSet {
self.setNeedsLayout()
}
}
var endGradientColorLightMode: UIColor = .blue
{
didSet {
self.setNeedsLayout()
}
}
lazy var myStartColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
if traitCollection.userInterfaceStyle == .dark {
return self.startGradientColorDarkMode
} else {
return self.startGradientColorLightMode
}
}
lazy var myEndColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
if traitCollection.userInterfaceStyle == .dark {
return self.endGradientColorDarkMode
} else {
return self.endGradientColorLightMode
}
}
private var gradientLayer: CAGradientLayer!
override class var layerClass: AnyClass {
return CAGradientLayer.self
}
override func layoutSubviews() {
self.gradientLayer = self.layer as? CAGradientLayer
self.gradientLayer.colors = [myStartColor.cgColor, myEndColor.cgColor]
self.gradientLayer.startPoint = CGPoint(x: 0, y: 0) // top
self.gradientLayer.endPoint = CGPoint(x: 1, y: 1) // bottom
}
}
class GradientTestViewController: UIViewController {
let testView = MyGradientView(frame: CGRect(x: 40, y: 100, width: 240, height: 240))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(testView)
let tapGR = UITapGestureRecognizer(target: self, action: #selector(didTap))
self.view.addGestureRecognizer(tapGR)
// just for example
// change colors from our defaults
// change dark mode to red-to-yellow
testView.startGradientColorDarkMode = .red
testView.endGradientColorDarkMode = .yellow
// change light mode to darkbown-to-lightBrown
testView.startGradientColorLightMode = UIColor(red: 0.45, green: 0.3, blue: 0.25, alpha: 1.0)
testView.endGradientColorLightMode = UIColor(red: 0.8, green: 0.65, blue: 0.3, alpha: 1.0)
}
@objc func didTap(tapGR: UITapGestureRecognizer) {
// we can change the gradient colors on-the-fly
if testView.startGradientColorDarkMode == UIColor.red {
// change dark mode to blue-to-cyan
testView.startGradientColorDarkMode = .blue
testView.endGradientColorDarkMode = .cyan
// change light mode to darkGreen-to-lightGreen
testView.startGradientColorLightMode = UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0)
testView.endGradientColorLightMode = .green
} else {
// change dark mode to red-to-yellow
testView.startGradientColorDarkMode = .red
testView.endGradientColorDarkMode = .yellow
// change light mode to darkbown-to-lightBrown
testView.startGradientColorLightMode = UIColor(red: 0.45, green: 0.3, blue: 0.25, alpha: 1.0)
testView.endGradientColorLightMode = UIColor(red: 0.8, green: 0.65, blue: 0.3, alpha: 1.0)
}
}
}