Skip to content

Instantly share code, notes, and snippets.

@mcfans
Created December 7, 2020 08:30
Show Gist options
  • Save mcfans/393e94622c19da7742ff07ed490c2378 to your computer and use it in GitHub Desktop.
Save mcfans/393e94622c19da7742ff07ed490c2378 to your computer and use it in GitHub Desktop.
UIView Animate Gradient
class GradientView: UIView {
var color: UIColor
init(_ color: UIColor) {
self.color = color
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var middleAlpha: CGFloat {
get {
if let layer = layer as? UIViewAnimatableGradientLayer {
return layer.middleAlpha
}
return 0
}
set {
if let layer = layer as? UIViewAnimatableGradientLayer {
layer.middleAlpha = newValue
// Change model layer property
layer.colors = [
color.withAlphaComponent(0).cgColor,
color.withAlphaComponent(newValue).cgColor,
color.cgColor,
]
}
}
}
override class var layerClass: AnyClass {
UIViewAnimatableGradientLayer.self
}
}
class UIViewAnimatableGradientLayer: CAGradientLayer {
@NSManaged var middleAlpha: CGFloat
override init() {
super.init()
}
override init(layer: Any) {
super.init(layer: layer)
if let layer = layer as? UIViewAnimatableGradientLayer {
self.middleAlpha = layer.middleAlpha
}
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
private class func isCustomAnimKey(key: String) -> Bool {
return key == "middleAlpha"
}
override class func needsDisplay(forKey key: String) -> Bool {
if self.isCustomAnimKey(key: key) {
return true
} else {
return super.needsDisplay(forKey: key)
}
}
override func action(forKey event: String) -> CAAction? {
if UIViewAnimatableGradientLayer.isCustomAnimKey(key: event) {
// Use a normal animatable property name to retrieve a CABasicAnimation, we need timing curve and duration info from it.
if let infoAction = super.action(forKey: "backgroundColor") as? CABasicAnimation {
infoAction.keyPath = "colors"
if let pLayer = presentation() {
infoAction.fromValue = pLayer.colors
}
infoAction.toValue = nil
return infoAction
}
setNeedsDisplay()
return nil
}
return super.action(forKey: event)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment