2012-02-12 75 views
30

我有一個標籤顯示一個數字,我想將其更改爲一個更高的數字,但是我想添加一些flare。 我想讓數字增加到更高的數字,並且輕鬆地輸入曲線,所以它會加速然後變慢。 這個答案顯示瞭如何讓它增加(第二個答案,而不是接受的答案),但我寧願將它製作成動畫,這樣我也可以使它稍微增加尺寸,然後再縮小以及緩和曲線。 how to do a running score animation in iphone sdk如何動畫UILabel中的遞增數字

任何想法如何最好地實現這一點? 謝謝

開始/結束號碼將被用戶輸入,我希望它在相同的時間量增加結束號碼。所以如果我開始10結束100或開始10結束1000我希望它在5秒鐘內數到最後的數字。

回答

3

您可以使用標誌來查看它是否必須上升或下降。 而不是for循環,使用while循環。 通過這種方式,您正在創建一個繼續前進的循環,所以您必須找到一種方法來阻止它,f.e.通過按鈕按下。

+0

也許我沒有解釋自己不夠。我已經添加了更多的問題。 我可以使用for循環或while循環從1號碼增加到另一個號碼。不過,我希望它能夠慢慢加速,然後放慢速度,直到最後。而且所有事情都要在一定的時間內發生。 – Darren 2012-02-12 19:00:09

+0

然後你可以使用2個for循環: - 一個去 - 一個倒數 如果你想使用一定的時間,你將不得不使用定時器,否則,它會發生就像CPU可以處理它一樣快。 – 2012-02-12 19:02:36

+0

我不需要倒數。我可以管理這些循環,我只需要讓這個過程在一定的時間內發生。 我是否可以將計數循環放入計時器中,讓過程在這段時間內發生,就像動畫一樣?我認爲定時器會告訴它發生的頻率。 – Darren 2012-02-12 19:11:09

61

我居然做了這樣一類只爲這所謂的UICountingLabel:

http://github.com/dataxpress/UICountingLabel

它允許您指定是否要計數模式爲線性,緩解,緩解了,或者緩解/出。緩進/緩出開始緩慢計數,加速,然後緩慢結束 - 無論您指定的時間長短如何。

它當前不支持根據當前值設置標籤的實際字體大小,但如果它是一個需求的功能,我可以添加對該標籤的支持。我的佈局中的大多數標籤沒有太多空間可以增長或縮小,所以我不確定您想如何使用它。但是,它的行爲完全像普通標籤,所以您也可以自行更改字體大小。

+0

謝謝,非常好;) – tamasgal 2013-02-28 19:18:21

+0

很高興喜歡它:)如果您有任何功能請求隨時在Github上張貼他們! – Tim 2013-02-28 22:19:43

+0

那很好。歡呼 – Desmond 2013-04-12 04:10:43

15

您可以使用GCD將延遲轉移到後臺線程。

這裏是值動畫(從1到100的10秒)的例子

float animationPeriod = 10; 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    for (int i = 1; i < 101; i ++) { 
     usleep(animationPeriod/100 * 1000000); // sleep in microseconds 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      yourLabel.text = [NSString stringWithFormat:@"%d", i]; 
     }); 
    } 
}); 
+0

當我把它粘貼到Xcode,我得到了一個「MAIN_QUEUE」錯誤。我必須用「dispatch_get_main_queue()」替換「MAIN_QUEUE」。否則,這是一個很好的答案。 – user3344977 2015-02-13 22:24:13

+0

@ user3344977,這是我對GCD工作的捷徑。 – malex 2015-02-13 22:34:17

+0

好的,謝謝你發佈它。上面大量提出的UICountingLabel答案無法正常工作,所以這是一個不錯的選擇。 – user3344977 2015-02-13 22:35:10

0

這是我做的:

- (void)setupAndStartCounter:(CGFloat)duration { 
    NSUInteger step = 3;//use your own logic here to define the step. 
    NSUInteger remainder = numberYouWantToCount%step;//for me it was 30 

    if (step < remainder) { 
     remainder = remainder%step; 
    } 

    self.aTimer = [self getTimer:[self getInvocation:@selector(animateLabel:increment:) arguments:[NSMutableArray arrayWithObjects:[NSNumber numberWithInteger:remainder], [NSNumber numberWithInteger:step], nil]] timeInterval:(duration * (step/(float) numberYouWantToCountTo)) willRepeat:YES]; 
    [self addTimerToRunLoop:self.aTimer]; 
} 

- (void)animateLabel:(NSNumber*)remainder increment:(NSNumber*)increment { 
    NSInteger finish = finalValue; 

    if ([self.aLabel.text integerValue] <= (finish) && ([self.aLabel.text integerValue] + [increment integerValue]<= (finish))) { 
     self.aLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)([self.aLabel.text integerValue] + [increment integerValue])]; 
    }else{ 
     self.aLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)([self.aLabel.text integerValue] + [remainder integerValue])]; 
     [self.aTimer invalidate]; 
     self.aTimer = nil; 
    } 
} 

#pragma mark - 
#pragma mark Timer related Functions 

- (NSTimer*)getTimer:(NSInvocation *)invocation timeInterval:(NSTimeInterval)timeInterval willRepeat:(BOOL)willRepeat 
{ 
    return [NSTimer timerWithTimeInterval:timeInterval invocation:invocation repeats:willRepeat]; 
} 

- (NSInvocation*)getInvocation:(SEL)methodName arguments:(NSMutableArray*)arguments 
{ 
    NSMethodSignature *sig = [self methodSignatureForSelector:methodName]; 
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; 
    [invocation setTarget:self]; 
    [invocation setSelector:methodName]; 
    if (arguments != nil) 
    { 
     id arg1 = [arguments objectAtIndex:0]; 
     id arg2 = [arguments objectAtIndex:1]; 
     [invocation setArgument:&arg1 atIndex:2]; 
     [invocation setArgument:&arg2 atIndex:3]; 
    } 
    return invocation; 
} 

- (void)addTimerToRunLoop:(NSTimer*)timer 
{ 
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 
} 
8

這裏@在迅速3.

malex的答案
func incrementLabel(to endValue: Int) { 
    let duration: Double = 2.0 //seconds 
    DispatchQueue.global().async { 
     for i in 0 ..< (endValue + 1) { 
      let sleepTime = UInt32(duration/Double(endValue) * 1000000.0) 
      usleep(sleepTime) 
      DispatchQueue.main.async { 
       self.myLabel.text = "\(i)" 
      } 
     } 
    } 
} 

但是,我強烈建議只需downloading this class from GitHub並將其拖到您的項目,我已經訴諸於你唱歌是因爲我的代碼中的時間似乎不適合低/高的計數。這門課很棒,看起來非常好。請參閱this medium article以供參考。

+1

我不認爲這是正確的。我認爲sleepTime配置錯誤。 – 2016-12-12 06:38:22

+0

很棒。我更正了答案,包括持續時間計算,但是,在我的測試中,數學是正確的,但睡眠/ dispatch.main過程有延遲,因此對於上面的代碼,完成需要大約4秒而不是2 。 – 2016-12-12 16:22:28

0

您還可以檢查https://github.com/leszek-s/LSCategories

它允許遞增/中的UILabel遞減數與代碼這樣一行:

[self.label lsAnimateCounterWithStartValue:10 endValue:100 duration:5 completionBlock:nil];