How to animate the textColor property of an UILabel?
This answer is obsolete, and is not a good solution for the original question. @strange 's answer below is much better and should be used instead of this answer: https://stackoverflow.com/a/20892927/76559
//Old answer below
The textColor
property is not specified as being animatable in the docs, so I don't think you can do it with a simple UIView animations block...
This could probably be done pretty crudely with an NSTimer
firing every couple of milliseconds, each time setting the colour gradually from one to the other.
I say this is crude because it would require an array or some other container of preset colour values going from the start colour to the finish colour, and I'm sure there's a way you could do this using core animation or something, I just don't know what it is.
Is it possible to animate UILabel's textcolor change?
Try this
[UIView transitionWithView:myLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
label.textColor = [UIColor redColor];
} completion:^(BOOL finished) {
}];
Animate UILabel text color in Swift
it is much easier than working with CALayer
let myLabel: UILabel!
UIView.animateWithDuration(2, animations: { () -> Void in
myLabel.backgroundColor = UIColor.redColor();
})
Thats it...
Edit
Ok, sorry I didn't knew what color you want to change... I have converted your example to swift code...
first
import QuartzCore
than
if let layer: CALayer = self.view.layer as CALayer? {
if let textLayer = CATextLayer() as CATextLayer? {
textLayer.string = "My string"
textLayer.foregroundColor = UIColor.whiteColor().CGColor
textLayer.frame = self.view.bounds
self.view.layer.addSublayer(textLayer)
UIView.animateWithDuration(0.5, animations: { () -> Void in
textLayer.foregroundColor = UIColor.redColor().CGColor
})
}
}
Is is possible to animate text color changing only in a part of text in iOS?
You can quite easily achieve this using CoreAnimation possibilities.
I've added a simple demo, you play with it here (just build the project and tap anywhere to see the animation).
The logic is the following:
- Create a custom subclass of UIView.
- When some text is set, create two similar
CATextLayers
, each with the same text and frame. - Set different
foregroundColor
andmask
for those layers. Themask
of the left layer will be the left part of the view, and themask
of the right layer will be the right part. - Animate
foregroundColor
for those layers (simultaneously).
The code of a custom view:
class CustomTextLabel: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .green
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private var textLayer1: CATextLayer?
private var textLayer2: CATextLayer?
func setText(_ text: String, fontSize: CGFloat) {
// create 2 layers with the same text and size, we'll set the colors for them later
textLayer1 = createTextLayer(text, fontSize: fontSize)
textLayer2 = createTextLayer(text, fontSize: fontSize)
// estimate the frame size needed for the text layer with such text and font size
let textSize = textLayer1!.preferredFrameSize()
let w = frame.width, h = frame.height
// calculate the frame such that both layers will be in center of view
let centeredTextFrame = CGRect(x: (w-textSize.width)/2, y: (h-textSize.height)/2, width: textSize.width, height: textSize.height)
textLayer1!.frame = centeredTextFrame
textLayer2!.frame = centeredTextFrame
// set up default color for the text
textLayer1!.foregroundColor = UIColor.yellow.cgColor
textLayer2!.foregroundColor = UIColor.yellow.cgColor
// set background transparent, that's very important
textLayer1!.backgroundColor = UIColor.clear.cgColor
textLayer2!.backgroundColor = UIColor.clear.cgColor
// set up masks, such that each layer's text is visible only in its part
textLayer1!.mask = createMaskLayer(CGRect(x: 0, y: 0, width: textSize.width/2, height: textSize.height))
textLayer2!.mask = createMaskLayer(CGRect(x: textSize.width/2, y: 0, width: textSize.width/2, height: textSize.height))
layer.addSublayer(textLayer1!)
layer.addSublayer(textLayer2!)
}
private var finishColor1: UIColor = .black, finishColor2: UIColor = .black
func animateText(leftPartColor1: UIColor, leftPartColor2: UIColor, rightPartColor1: UIColor, rightPartColor2: UIColor) {
finishColor1 = leftPartColor2
finishColor2 = rightPartColor2
if let layer1 = textLayer1, let layer2 = textLayer2 {
CATransaction.begin()
let animation1 = CABasicAnimation(keyPath: "foregroundColor")
animation1.fromValue = leftPartColor1.cgColor
animation1.toValue = leftPartColor2.cgColor
animation1.duration = 3.0
layer1.add(animation1, forKey: "animation1")
let animation2 = CABasicAnimation(keyPath: "foregroundColor")
animation2.fromValue = rightPartColor1.cgColor
animation2.toValue = rightPartColor2.cgColor
animation2.duration = 3.0
layer2.add(animation2, forKey: "animation2")
CATransaction.setCompletionBlock {
self.textLayer1?.foregroundColor = self.finishColor1.cgColor
self.textLayer2?.foregroundColor = self.finishColor2.cgColor
}
CATransaction.commit()
}
}
private func createTextLayer(_ text: String, fontSize: CGFloat) -> CATextLayer {
let textLayer = CATextLayer()
textLayer.string = text
textLayer.fontSize = fontSize // TODO: also set font name
textLayer.contentsScale = UIScreen.main.scale
return textLayer
}
private func createMaskLayer(_ holeRect: CGRect) -> CAShapeLayer {
let layer = CAShapeLayer()
let path = CGMutablePath()
path.addRect(holeRect)
path.addRect(bounds)
layer.path = path
layer.fillRule = CAShapeLayerFillRule.evenOdd
layer.opacity = 1
return layer
}
}
The calls of a custom view:
class ViewController: UIViewController {
var customLabel: CustomTextLabel!
override func viewDidLoad() {
super.viewDidLoad()
let viewW = view.frame.width, viewH = view.frame.height
let labelW: CGFloat = 200, labelH: CGFloat = 50
customLabel = CustomTextLabel(frame: CGRect(x: (viewW-labelW)/2, y: (viewH-labelH)/2, width: labelW, height: labelH))
customLabel.setText("Optimizing...", fontSize: 20)
view.addSubview(customLabel)
let tapRecogniner = UITapGestureRecognizer(target: self, action: #selector(onTap))
view.addGestureRecognizer(tapRecogniner)
}
@objc func onTap() {
customLabel.animateText(leftPartColor1: UIColor.blue,
leftPartColor2: UIColor.red,
rightPartColor1: UIColor.white,
rightPartColor2: UIColor.black)
}
}
How to animate text color of a UILabel like a progress bar
To achieve it, follow below steps:
- Create 2
UILabel
(trackLabel
andprogressLabel
). trackLabel
haveblackColor
andprogressLabel
haveredColor
.- Make
progressLabel
overlaptrackLabel
, same leading, top and bottom. - Give
trackLabel
full width with text andprogressLabel
0 width. - Set
progressLabel.lineBreakMode = NSLineBreakByClipping;
- When you need to animate progress, increase width of
progressLabel
.
For more detail, you can check my demo project.
How to animate (fade) UILabel textColor in Swift?
UILabel.textColor
does not support animation. But you can animate CATextLayer
:
Swift:
let textLayer = CATextLayer()
textLayer.string = "Your text"
textLayer.foregroundColor = yourFirstColor
textLayer.frame = yourButton.bounds
yourButton.layer.addSublayer(textLayer)
UIView.animateWithDuration(1) {
textLayer.foregroundColor = yourSecondColor
}
Objective C:
CATextLayer *textLayer = [CATextLayer layer];
[textLayer setString:@"Your text"];
[textLayer setForegroundColor:yourFirstColor];
[textLayer setFrame:yourButton.bounds];
[[yourButton layer] addSublayer:textLayer];
[UIView animateWithDuration:1 animations:^{
textLayer.foregroundColor = yourSecondColor;
}];
Animating UILabel textColor property with UIViewPropertyAnimator
As said in the comments, the textColor
property can not be animated.
However, there is a technique called color interpolation, which might be a nice workaround.
You can find multiple ways to solve this in this thread, however, I provide you with one solution also:
extension UIColor {
var components: (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
let components = self.cgColor.components!
switch components.count == 2 {
case true :
return (r: components[0], g: components[0], b: components[0], a: components[1])
case false:
return (r: components[0], g: components[1], b: components[2], a: components[3])
}
}
static func interpolate(from fromColor: UIColor, to toColor: UIColor, with progress: CGFloat) -> UIColor {
let fromComponents = fromColor.components
let toComponents = toColor.components
let r = (1 - progress) * fromComponents.r + progress * toComponents.r
let g = (1 - progress) * fromComponents.g + progress * toComponents.g
let b = (1 - progress) * fromComponents.b + progress * toComponents.b
let a = (1 - progress) * fromComponents.a + progress * toComponents.a
return UIColor(red: r, green: g, blue: b, alpha: a)
}
}
Then, all you have to do is this in the function you call when the slider's value has changed:
@objc func sliderChanged(_ sender: UISlider) {
animator.fractionComplete = CGFloat(sender.value)
yourLabel.textColor = UIColor.interpolate(from: fromColor, to: toColor, with: sender.value)
}
You are not animating the textColor
, rather you change it to a different color with each call to sliderChanged
, but the change appears gradual and does not jump from your start color to your second color, so I think it should achieve your desired result.
How to animate text color change partially in UILabel with custom control?
You could do this by having your white selector act as a mask. Duplicate your three labels -- one set for white, the other for grey -- and position them overlapping on each other. Add the three grey ones as subviews of the white selector and cause the white selector to clipsToBounds
. When you animate the selector, animate the subview labels in the opposite direction at the same rate and they will appear to stay in place but become revealed as your white bar moves.
Related Topics
Spritekit Not Respecting Zposition
Swift + Firebase Security Not Working
How to Create Custom Album in Swift 3 iOS 10
How to Make a Countdown Timer Like in a Music Player
iOS UIlabel Autoshrink So Word Doesn't Truncate to Two Lines
How to Know Which Line of Code Has Caused My iOS App to Crash in Xcode 9
How to Detect If My Device Is an iPhone x in Swift 4
Pass a Nsdictionary as Parameter to UItapgesturerecognizer
iOS Getting My Location Regularly and Setting Button to Get My Location - Google Map Not Working
Should I Use Realm Objective-C or Realm Swift in My Mixed Objective-C/Swift Project
How to Show Viewcontroller from a Non-Viewcontroller Helper Class
Fix Cursor Size for Modified Paragraph Spacing in Uitextview
Populating Input Text Field in Wkwebview
Map Object into 2D Array Swift for Tableview Sections
Gcm Support for iOS Application When Application in Background or Killed
iOS 8 Uitableview First Row Has Wrong Height
Media_Err_Decode on HTML5 Video in iOS UIwebview After Many Plays
Swift 4.2 Make Bottom of Tableview Move Up When Keyboard Shows