Tạo hiệu ứng văn bản UILabel giữa hai số?


80

Tôi là người mới lập trình iPhone và Mac (được phát triển cho Windows trước đây) và tôi có một câu hỏi:

Làm cách nào để tạo hoạt ảnh thuộc texttính của một UILabelgiữa hai số, ví dụ từ 5 đến 80 theo kiểu Dễ thấy? Có thể với CoreAnimation? Tôi đã tìm kiếm trên Google trong một giờ, nhưng tôi không tìm thấy bất kỳ điều gì giải quyết được vấn đề của mình. Điều tôi muốn: Tạo hiệu ứng cho tiền của người dùng bằng một trò chơi đơn giản. Nó trông không đẹp lắm khi nó chỉ tăng từ 50 lên 100 hoặc tương tự như vậy mà không có hoạt ảnh.

Bất cứ ai có một ý tưởng làm thế nào để làm điều đó?

Cảm ơn!


2
Đây là một câu hỏi cũ nhưng Pop (khung hoạt hình của Facebook) sẽ là một giải pháp tốt. Bạn có thể tạo hoạt ảnh trực tiếp cho thuộc tính văn bản.
jrturton

Câu trả lời:


160

Bạn có thể sử dụng chuyển đổi tự động. Nó hoạt động hoàn toàn tốt:

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

Mã này hoạt động nếu myLabel đã được hiển thị. Nếu không myLabel.layer sẽ là nil và hoạt ảnh sẽ không được thêm vào đối tượng.


trong Swift 4 đó sẽ là:

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

2
Tôi đã thử điều này (đảm bảo rằng lớp không phải là con số không khi hoạt ảnh được thêm vào), nhưng văn bản vẫn không hoạt động. Có gì khác không?
elsurudo

5
Chỉ là một lưu ý nhỏ, bạn phải thêm hoạt ảnh ngay trước khi bạn thay đổi văn bản mỗi khi bạn muốn thay đổi văn bản và có hiệu ứng mờ dần xảy ra. Tuy nhiên, bạn không phải khởi tạo một Chuyển đổi mới mỗi lần, cùng một phiên bản có thể được sử dụng lại nhiều lần.
Lance

2
Câu hỏi đặt ra là làm thế nào để làm sinh động các con số, ví dụ như tăng giá trị của chúng, không làm mờ dần về mặt đồ thị giữa hai con số. Sử dụng PRTween: github.com/shu223/TweenDemo/tree/…
jowie.

14
Trên thực tế, nếu bạn đặt removedOnCompletionthành NOtrên ví dụ của CATransition, mọi thay đổi đối với nhãn textsẽ được làm động.
Mark Adams

1
@kientux Không có gì đặc biệt về khóa changeTextTransition. Nó chỉ đơn giản là một chuỗi xác định hoạt ảnh , có nghĩa là đó là một chuỗi mà bạn có thể sử dụng sau này để xác định hoạt ảnh mà bạn đã thêm trước đó. Nếu sau này bạn không cần xác định hoạt ảnh của mình, bạn chỉ cần chỉ định nil.
jamesk

27

Nó hoạt động tốt!

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)

1
Làm việc còn bởi giá trị khác, chẳng hạn như thay đổi imagecủa mộtUIImageView
SaltyNuts

7

Tôi đã tìm thấy một công cụ tuyệt vời để chỉnh sửa các giá trị với nhiều chức năng định thời gian khác nhau được gọi là PRTween . Cài đặt các lớp và tạo một số mã dọc theo các dòng sau:

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

Làm việc một điều trị cho tôi. :)


5

Nếu bạn muốn nó đếm lên và đếm ngược với số mới đẩy số trước đó đi (như một mã hoặc thứ gì đó):

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

Chào! Cảm ơn câu trả lời của bạn! Điều này hoạt động khá gọn gàng. Tôi chỉ có câu hỏi khác. Bạn có biết cách tạo hiệu ứng cho các phần của văn bản không? Thích ký tự thứ 3 và để phần còn lại không thay đổi? Tôi muốn triển khai một nhãn hiển thị số. Nếu giá trị thay đổi chỉ các chữ số sẽ hoạt ảnh, điều đó thực sự đã thay đổi.
Lars Petersen

Cá nhân tôi muốn sử dụng CoreGraphics và CoreAnimation cho loại việc này. Hoặc bạn có thể gian lận và xâu chuỗi một vài nhãn lại với nhau? Phụ thuộc vào mức độ phức tạp của bạn chuỗi.
Adam Waite

3

Trong Swift 2.0, sử dụng UIView.transitionWithView()phương pháp:

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

1

một sự thay thế đơn giản khác

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)))"
            }
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.