开发者

Animate UILabel text between two numbers?

I'm new to iPhone and Mac programming (developed for Windows before), and I've got a question:

How do I animate the text property of an UILabel between two numbers, e.g. from 5 to 80 in an Ease-Out style? Is it possible with CoreAnimation? I have been searching on Google for an hour, but I haven't found anything solving my problem. What I want: Animate the users money for a simple game. It doesn't look very nice when it j开发者_如何转开发ust goes from 50 to 100 or something like that without animation.

Anyone having an idea how to do that?

Thanks!


You can use the automatic transitions. It's working perfectly well :

// Add transition (must be called after myLabel has been displayed)
 CATransition *animation = [CATransition animation];
animation.duration = 1.0;
animation.type = kCATransitionFade;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[myLabel.layer addAnimation:animation forKey:@"changeTextTransition"];

// Change the text
myLabel.text = newText;

This code works if myLabel is already displayed. If not myLabel.layer will be nil and the animation will not be added to the object.


in Swift 4 that would be:

let animation: CATransition = CATransition()
animation.duration = 1.0
animation.type = kCATransitionFade
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
myLabel.layer.add(animation, forKey: "changeTextTransition")


It works well!

Objective-C

[UIView transitionWithView:self.label 
                  duration:.5f 
                   options:UIViewAnimationOptionCurveEaseInOut | 
                           UIViewAnimationOptionTransitionCrossDissolve 
                animations:^{

    self.label.text = rand() % 2 ? @"111!" : @"42";

} completion:nil];

Swift 2

UIView.transitionWithView(label, duration: 0.25, options: [.CurveEaseInOut, .TransitionCrossDissolve], animations: {
    self.label.text = (arc4random() % 2 == 0) ? "111" : "222"
}, completion: nil)

Swift 3, 4, 5

UIView.transition(with: label, duration: 0.25, options: [.curveEaseInOut, .transitionCrossDissolve], animations: {
    self.label.text = (arc4random() % 2 == 0) ? "111" : "222"
}, completion: nil)


I found a great engine for tweening values with a variety of different timing functions called PRTween. Install the classes and create some code along these lines:

- (IBAction)tweenValue
{
    [[PRTween sharedInstance] removeTweenOperation:activeTweenOperation];
    PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:0.0 endValue:100.0 duration:1.0];
    activeTweenOperation = [[PRTween sharedInstance] addTweenPeriod:period
                                                             target:self
                                                           selector:@selector(update:)
                                                     timingFunction:&PRTweenTimingFunctionCircOut];
}

- (void)update:(PRTweenPeriod*)period
{
    self.animatingView.center = CGPointMake(period.tweenedValue + 100.0, 200.0);
    self.valueLabel.text = [NSString stringWithFormat:@"%.2f", period.tweenedValue];
}

Works a treat for me. :)


If you kind of want it to count up and down with the new number pushing the previous number away (like a ticker or something):

let animation = CATransition()
animation.removedOnCompletion = true
animation.duration = 0.2
animation.type = kCATransitionPush
animation.subtype = newValue > value ? kCATransitionFromTop : kCATransitionFromBottom
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
valueLabel.layer.addAnimation(animation, forKey:"changeTextTransition")


In Swift 2.0, using the UIView.transitionWithView() method:

UIView.transitionWithView(self.payPeriodSummaryLabel,
        duration: 0.2,
        options: [.CurveEaseInOut, .TransitionCrossDissolve],
        animations: { () -> Void in
            self.label.text = "your text value"
        }, completion: nil)


another simple alternative

extension UILabel {    
    func countAnimation(upto: Double) {
        let from: Double = text?.replace(string: ",", replacement: ".").components(separatedBy: CharacterSet.init(charactersIn: "-0123456789.").inverted).first.flatMap { Double($0) } ?? 0.0
        let steps: Int = 20
        let duration = 0.350
        let rate = duration / Double(steps)
        let diff = upto - from
        for i in 0...steps {
            DispatchQueue.main.asyncAfter(deadline: .now() + rate * Double(i)) {
                self.text = "\(from + diff * (Double(i) / Double(steps)))"
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜