Skip to content

Instantly share code, notes, and snippets.

@abhi21git
Created April 4, 2023 11:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abhi21git/f01bfdd26fdf8cfeffdb6e54218fa3aa to your computer and use it in GitHub Desktop.
Save abhi21git/f01bfdd26fdf8cfeffdb6e54218fa3aa to your computer and use it in GitHub Desktop.
An animatable label with push text animation which can either be used from storyboard or programatically.
//
// UIAnimatableLabel.swift
//
// Created by Abhishek Maurya on 04/04/23.
//
import UIKit
// MARK: - UIAnimatableLabel
final class UIAnimatableLabel: UILabel {
/// Provide a comma separated string
@IBInspectable var animatableText: String = "" {
didSet {
animatableTexts = animatableText.components(separatedBy: ",")
}
}
/// Provide an array of string
var animatableTexts: [String] = [] {
didSet {
handleAnimation()
}
}
private func handleAnimation(with index: Int = 0) {
guard animatableTexts.count > 1 else {
removeAnimatedText()
if let text = animatableTexts.first {
self.text = text
}
return
}
setAnimated(text: animatableTexts[index], for: 0.25, after: 2.5) { [weak self] finished in
guard let self = self, finished else { return }
self.handleAnimation(with: (index + 1) % self.animatableTexts.count)
}
}
private func setAnimated(text string: String, for duration: CGFloat = 0.25, after delay: CGFloat = 0, completion: ((Bool) -> Void)? = nil) {
removeAnimatedText()
CATransaction.begin()
CATransaction.setCompletionBlock { [weak self] in
completion?(self?.layer.animation(forKey: kCATransition) != nil)
}
let currentLayerTime = layer.convertTime(CACurrentMediaTime(), from: nil)
let animation: CATransition = CATransition()
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
animation.type = .push
animation.beginTime = currentLayerTime + delay
animation.subtype = .fromTop
animation.duration = duration
animation.isRemovedOnCompletion = false
animation.fillMode = .backwards
text = string
layer.add(animation, forKey: kCATransition)
CATransaction.commit()
}
private func removeAnimatedText() {
layer.removeAnimation(forKey: kCATransition)
}
}
@abhi21git
Copy link
Author

AnimatableLabel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment