Last active
July 3, 2019 14:06
-
-
Save vialyx/b4fc9f700aea17c71a89d51b5fad6f72 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MaskedLabelView: UIView { | |
weak var label: UILabel! | |
var startColor: UIColor = .blue | |
var endColor: UIColor = .black | |
var duration: CFTimeInterval = 2.0 | |
var repeatCount: Float = Float.infinity | |
var completion: ((Bool) -> Void)? | |
// CAGradientLayer provide api to work with gradient colors | |
lazy var gradientLayer: CAGradientLayer = { | |
let gradientLayer = CAGradientLayer() | |
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) | |
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) | |
gradientLayer.colors = [ | |
startColor.cgColor, | |
endColor.cgColor | |
] | |
gradientLayer.locations = [ | |
0.0, | |
0.1 | |
] as [NSNumber] | |
return gradientLayer | |
}() | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
configure() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
configure() | |
} | |
private func configure() { | |
// Create internal UILabel and setup it as mask in self | |
let lbl = UILabel(frame: frame) | |
lbl.numberOfLines = 0 | |
mask = lbl | |
label = lbl | |
} | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
// Resize label and gradient layer on self resizing | |
label.frame = frame | |
gradientLayer.frame = frame | |
} | |
func animate() { | |
// Setup actual colors | |
gradientLayer.colors = [ | |
startColor.cgColor, | |
endColor.cgColor | |
] | |
// Add Gradient to self layer | |
gradientLayer.removeFromSuperlayer() | |
layer.addSublayer(gradientLayer) | |
// Create gradient locations changes animation | |
let anim = CABasicAnimation(keyPath: "locations") | |
anim.delegate = self | |
anim.fromValue = [0.0, 0.1] | |
anim.toValue = [1.0, 1.0] | |
anim.duration = duration | |
anim.repeatCount = repeatCount | |
anim.fillMode = .forwards | |
anim.isRemovedOnCompletion = false | |
gradientLayer.removeAllAnimations() | |
gradientLayer.add(anim, forKey: nil) | |
} | |
} | |
extension MaskedLabelView: CAAnimationDelegate { | |
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { | |
if (anim as? CAPropertyAnimation)?.keyPath == "locations" { | |
// Call completion block to notify about animation completion | |
completion?(flag) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment