How to Animate the Background Color of a Uilabel

How to animate the background color of a UILabel?

I can't find it documented anywhere, but it appears the backgroundColor property of UILabel is not animatable, as your code works fine with a vanilla UIView. This hack appears to work, however, as long as you don't set the background color of the label view itself:

#import 

...

theLabel.layer.backgroundColor = [UIColor whiteColor].CGColor;

[UIView animateWithDuration:2.0 animations:^{
theLabel.layer.backgroundColor = [UIColor greenColor].CGColor;
} completion:NULL];

How can I animate the background color of a label using Swift

try animate layer.backgroundColor instead backgroundColor

this code works for me

    UIView.animate(withDuration: 2, delay: 0.0, options:[UIViewAnimationOptions.repeat, UIViewAnimationOptions.autoreverse], animations: {
self.label.layer.backgroundColor = UIColor(red: 0/255, green: 185/255, blue: 215/255, alpha: 1.0).cgColor
self.label.layer.backgroundColor = UIColor(red: 0/255, green: 78/255, blue: 215/255, alpha: 1.0).cgColor
self.label.layer.backgroundColor = UIColor(red: 0/255, green: 215/255, blue: 138/255, alpha: 1.0).cgColor
}, completion: nil)

Trying to animate backgroundcolor on a uilabel to achieve a 'fade' effect, but it applies instantly

Background color of UILabel isn't animatable. See How to animate the background color of a UILabel? for a possible workaround.

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
})
}
}

Color Animation of UILabel in swift

As far as I know, you need to use two separate labels. Here is how you can do the animation:

You can put the green label on the screen in the same spot with the same constraints as the red label and then set it to be off-screen at first (Run this code in viewDidLoad):

playAgainButton.center = CGPointMake(playAgainButton.center.x - 500, playAgainButton.center.y)

It sounds to me like you want the red label to move from on screen to the left off of the screen and the green label to move from off-screen to the left on to the screen...Here is the animation:

UIView.animateWithDuration(0.5, animations: { () -> Void in

self.redLabel.center = CGPointMake(self.redLabel.center.x + 500, self.redLabel.center.y)

self.greenLabel.center = CGPointMake(self.redLabel.center.x + 500, self.greenLabel.center.y)

})

You can always mess with the animations to change the duration (I have it set to 0.5 seconds)

Hope this helps!

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.

UIView.animate does not work on background color

Well, I dont know the reason behind this why Apple didnt allow to animate the background color change, but here is a solution provided in another stackoverflow's post, which is as follows:

#import 

...

theLabel.layer.backgroundColor = [UIColor whiteColor].CGColor;

[UIView animateWithDuration:2.0 animations:^{
theLabel.layer.backgroundColor = [UIColor greenColor].CGColor;
} completion:NULL];

Another hack is that you make a UIView behind UILabel, and give UILabel clear color, this way you can animate the color change of UIView

Change label background color using animation in iOS

I can't find it documented anywhere, but it appears the backgroundColor property of UILabel is not animatable. This hack appears to work, however, as long as you don't set the background color of the label view itself:

*#import *


//Add this in ViewDidLoad

for (UILabel *label in self.lblArray)
{
label.layer.backgroundColor = [UIColor whiteColor].CGColor;
}

-(void)animationTestIntoLoop
{
__block NSMutableArray* animationBlocks = [NSMutableArray new];
typedef void(^animationBlock)(BOOL);

// getNextAnimation
// removes the first block in the queue and returns it
animationBlock (^getNextAnimation)(void) = ^{

if ([animationBlocks count] > 0){
animationBlock block = (animationBlock)[animationBlocks objectAtIndex:0];
[animationBlocks removeObjectAtIndex:0];
return block;
} else {
return ^(BOOL finished){
animationBlocks = nil;
};
}
};

for (UILabel *label in self.lblArray)
{
[animationBlocks addObject:^(BOOL finished){

[UIView animateWithDuration:2.0 animations:^{
label.layer.backgroundColor = [UIColor redColor].CGColor;
} completion:getNextAnimation()];
}];
}
getNextAnimation()(YES);
}

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;
}];

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:

  1. Create a custom subclass of UIView.
  2. When some text is set, create two similar CATextLayers, each with the same text and frame.
  3. Set different foregroundColor and mask for those layers. The mask of the left layer will be the left part of the view, and the mask of the right layer will be the right part.
  4. 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)
}

}


Related Topics



Leave a reply



Submit