UILabel-Text zwischen zwei Zahlen animieren?


80

Ich bin neu in der iPhone- und Mac-Programmierung (zuvor für Windows entwickelt) und habe eine Frage:

Wie animiere ich die textEigenschaft einer UILabelzwischen zwei Zahlen, z. B. von 5 bis 80, in einem Ease-Out-Stil? Ist es möglich mit CoreAnimation? Ich habe eine Stunde lang bei Google gesucht, aber nichts gefunden, was mein Problem lösen könnte. Was ich will: Animieren Sie das Geld der Benutzer für ein einfaches Spiel. Es sieht nicht sehr gut aus, wenn es nur von 50 auf 100 geht oder so etwas ohne Animation.

Hat jemand eine Idee, wie das geht?

Vielen Dank!


2
Dies ist eine alte Frage, aber Pop (Facebook-Animations-Framework) wäre eine gute Lösung. Sie können die Texteigenschaft direkt animieren.
Jrturton

Antworten:


160

Sie können die automatischen Übergänge verwenden. Es funktioniert perfekt:

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

Dieser Code funktioniert, wenn myLabel bereits angezeigt wird. Wenn nicht, ist myLabel.layer gleich Null und die Animation wird dem Objekt nicht hinzugefügt.


in Swift 4 wäre das:

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

2
Ich habe dies versucht (um sicherzustellen, dass die Ebene beim Hinzufügen der Animation nicht Null ist), aber der Text wird immer noch nicht animiert. Irgendwelche anderen Fallstricke?
Elsurudo

5
Nur eine Randnotiz: Sie müssen die Animation hinzufügen, bevor Sie den Text jedes Mal ändern, wenn Sie den Text ändern möchten, und den Überblendungseffekt erzielen. Sie müssen jedoch nicht jedes Mal einen neuen Übergang instanziieren, dieselbe Instanz kann immer wieder verwendet werden.
Lance

2
Die Frage war, wie man die Zahlen animiert, z. B. indem man ihren Wert erhöht, ohne grafisch zwischen den beiden zu verblassen. Verwenden Sie PRTween: github.com/shu223/TweenDemo/tree/…
jowie

14
Eigentlich, wenn Sie festgelegt , removedOnCompletionum NOauf die Instanz CATransition, jede Änderung des Labels textwird animiert werden.
Mark Adams

1
@kientux Der Schlüssel hat nichts Besonderes changeTextTransition. Es ist einfach eine Zeichenfolge, die die Animation identifiziert. Dies bedeutet, dass Sie diese Zeichenfolge später verwenden können, um eine zuvor hinzugefügte Animation zu identifizieren. Wenn Sie Ihre Animation später nicht identifizieren müssen, können Sie sie einfach angeben nil.
Jamesk

27

Es funktioniert gut!

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

1
Arbeitete auch für andere Eigenschaften, wie das Ändern der imagevon aUIImageView
SaltyNuts

7

Ich habe eine großartige Engine zum Tweening von Werten mit einer Vielzahl verschiedener Timing-Funktionen namens PRTween gefunden . Installieren Sie die Klassen und erstellen Sie Code in dieser Richtung:

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

Arbeitet ein Vergnügen für mich. :) :)


5

Wenn Sie möchten, dass es mit der neuen Nummer auf und ab zählt und die vorherige Nummer wegschiebt (wie ein Ticker oder so):

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

Hallo! Danke für deine Antwort! Das funktioniert ziemlich ordentlich. Ich habe nur auf weitere Frage. Wissen Sie, wie Sie nur Teile des Textes animieren können? Wie das 3. Zeichen und den Rest unverändert lassen? Ich möchte ein Etikett implementieren, das Zahlen anzeigt. Wenn sich der Wert ändert, werden nur die Ziffern animiert, das hat sich tatsächlich geändert.
Lars Petersen

Persönlich würde ich CoreGraphics und CoreAnimation für solche Dinge verwenden. Oder könnten Sie ein paar Labels betrügen und aneinander reihen? Hängt davon ab, wie komplex Ihre Zeichenfolge ist.
Adam Waite

3

Verwenden Sie in Swift 2.0 die folgende UIView.transitionWithView()Methode:

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

1

eine andere einfache 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)))"
            }
        }
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.