对两个数字之间的UILabel文本进行动画处理?


80

我是iPhone和Mac编程的新手(以前为Windows开发),但是我有一个问题:

如何以缓和样式为两个数字之间的text属性设置动画UILabel,例如从580?有可能CoreAnimation吗?我已经在Google上搜索了一个小时,但没有找到任何解决我的问题的方法。我想要的:为用户制作一个简单游戏的资金。当它从50变为100或没有动画时类似的效果就不太好了。

有人知道该怎么做吗?

谢谢!


2
这是一个古老的问题,但是Pop(Facebook动画框架)将是一个很好的解决方案。您可以直接为text属性设置动画。
jrturton

Answers:


160

您可以使用自动转换。运行良好:

// 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;

如果已经显示myLabel,则此代码有效。否则,myLabel.layer将为nil,并且动画将不会添加到该对象。


Swift 4中,将是:

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

2
我尝试了这一点(确保添加动画时该层不为零),但是文本仍然没有动画。还有其他陷阱吗?
elsurudo 2013年

5
附带说明一下,每次更改文本并发生淡入淡出效果时,都必须在更改文本之前添加动画。但是,您不必每次都实例化一个新的Transition,可以重复使用同一实例。
Lance

2
问题是如何为数字设置动画,例如增加它们的值,而不是在两者之间以图形方式消失。使用PRTween:github.com/shu223/TweenDemo/tree/…– jowie 2013
6

14
实际上,如果您在的实例上将设置removedOnCompletionNO,则CATransition对标签的每次更改text都会进行动画处理。
Mark Adams

1
@kientux密钥没有什么特别的changeTextTransition。它只是一个标识动画的字符串,这意味着它是一个字符串,您以后可以使用它来标识先前添加的动画。如果以后不需要识别动画,只需指定即可nil
jamesk

27

效果很好!

目标C

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

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

} completion:nil];

迅捷2

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

斯威夫特3,4,5

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

1
也为其他属性工作过,例如更改imageUIImageView
SaltyNuts的

7

我发现了一个强大的引擎,可以使用称为PRTween的各种不同定时功能来补间值。安装这些类并按照以下方式创建一些代码:

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

为我工作。:)


5

如果您想让它随着新数字向上或向下计数,则将前一个数字移开(例如代码)。

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

嘿! 感谢您的回答!这工作非常整洁。我只有进一步的问题。您知道如何仅对文本的一部分进行动画处理吗?像第三个角色一样,让其余部分保持不变?我想实现一个显示数字的标签。如果值更改,则仅数字将动画,该数字实际上已更改。
拉尔斯·彼得森

就个人而言,我会考虑将CoreGraphics和CoreAnimation用于此类事情。或者,您可以欺骗并把几个标签串在一起?取决于字符串的复杂程度。
亚当·怀特

3

在Swift 2.0中,使用以下UIView.transitionWithView()方法:

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

1

另一个简单的选择

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)))"
            }
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.