iPad: Animate UILabels color changing
I have a label w开发者_开发技巧hich pops up displaying points in my application. I am using the following code to make the label get larger in scale, then smaller. I would also like to animate the color changing from purple to green. Can someone point me to a resource in achieving this?
mLabel.textColor = [UIColor purpleColor];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
mLabel.transform = CGAffineTransformMakeScale(1.5,1.5);
[UIView setAnimationRepeatCount:1];
mLabel.transform = CGAffineTransformMakeScale(0.5,0.5);
mLabel.textColor = [UIColor greenColor];
[UIView commitAnimations];
You can use iOS 4.0's view transition method to do this:
[UIView transitionWithView:statusLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
[statusLabel setTextColor:[UIColor whiteColor]];
[statusLabel setShadowColor:[UIColor blackColor]];
} completion:nil];
Unfortunately, the color doesn't animate with UIView animations. The answers to this question give some good workarounds without using Core Animation.
If you don't mind using a CATextLayer instead of a UILabel, then the color (and the scaling in your example) can be animated like this:
#import <QuartzCore/QuartzCore.h>
//Also need to add QuartzCore framework to project (as well as the import).
//
-(void)animateTextLayer {
CGFloat animationDuration = 5;
CATextLayer *textLayer = [CATextLayer layer];
[textLayer setString:@"Hello World"];
[textLayer setForegroundColor:[UIColor purpleColor].CGColor];
[textLayer setFontSize:30];
[textLayer setFrame:CGRectMake(20, 200, 300, 40)];
[[self.view layer] addSublayer:textLayer];
CABasicAnimation *colorAnimation = [CABasicAnimation
animationWithKeyPath:@"foregroundColor"];
colorAnimation.duration = animationDuration;
colorAnimation.fillMode = kCAFillModeForwards;
colorAnimation.removedOnCompletion = NO;
colorAnimation.fromValue = (id)[UIColor purpleColor].CGColor;
colorAnimation.toValue = (id)[UIColor greenColor].CGColor;
colorAnimation.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionLinear];
CAKeyframeAnimation *scaleAnimation = [CAKeyframeAnimation
animationWithKeyPath:@"transform"];
NSArray *scaleValues = [NSArray arrayWithObjects:
[NSValue valueWithCATransform3D:CATransform3DScale(textLayer.transform, 1, 1, 1)],
[NSValue valueWithCATransform3D:CATransform3DScale(textLayer.transform, 1.5, 1.5, 1)],
[NSValue valueWithCATransform3D:CATransform3DScale(textLayer.transform, 0.5, 0.5, 1)], nil];
[scaleAnimation setValues:scaleValues];
scaleAnimation.fillMode = kCAFillModeForwards;
scaleAnimation.removedOnCompletion = NO;
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.duration = animationDuration;
animationGroup.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionLinear];
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.removedOnCompletion = NO;
animationGroup.animations =
[NSArray arrayWithObjects:colorAnimation, scaleAnimation, nil];
[textLayer addAnimation:animationGroup forKey:@"animateColorAndScale"];
}
The reason that textColor is not animatable is that UILabel uses a regular CALayer instead of a CATextLayer.
To make textColor animatable (as well as text, font, etc.) we can subclass UILabel and make it use a CATextLayer.
This is quite a lot of work, but luckily I already did it :-)
You can find a complete explanation + a drop-in open source replacement for UILabel in this article
If you need to use IB colors that are specified for highlighted or selected states and want to animate the color change with fade out effect you can use next code:
Swift:
@IBAction func buttonAction(sender: AnyObject) {
// Set selected to leave same color as for highlighted
// (default=black, highlighted=red, selected=red)
self.openAllButton.selected = true
// Delay before the color change animation
let delayInSeconds = 0.1;
let delay = delayInSeconds * Double(NSEC_PER_SEC)
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay));
dispatch_after(popTime, dispatch_get_main_queue(), {
// Animate color change
UIView.transitionWithView(self.openAllButton, duration: 1.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: { () -> Void in
self.openAllButton.selected = false // selected->default
}) { (v:Bool) -> Void in
}
});
}
This line of code works for me. Make sure to set the Options to Cross Dissolve Swift:
static func animationButtonTextColor(button : UIButton, toColor : UIColor, duration : NSTimeInterval) {
UIView.transitionWithView(button, duration: duration, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {
button.setTitleColor(toColor, forState: .Normal)
}, completion: nil)
}
Add this before your call to commitAnimations
:
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:mLabel cache:YES];
Try This:
[UIView animateWithDuration:0.5 animations:^{
label.alpha=0.3;
}completion:^(BOOL finished)
{
label.backgroundcolor=[uicolor purplecolor];
[UIView animateWithDuration:0.5 animations:^{
label.alpha=1.0;
}completion:^(BOOL finished)
{
}];
}];
精彩评论