2015-07-01 29 views
0

我已經實現了一個UIProgressView作爲倒數計時器,它的值在1.5秒內從1.0減少到0.0。使UIProgressView作爲倒數計時器

它已經工作,但問題是它採取了時間長於1.5 秒,這是約2.0 - 2.5秒,直到進度視圖值達到0.0

對於它在短短1.5上運行,我下降每次調用進度值爲0.001。減少方法是在0.0015秒的時間間隔後調用。

以下是我該怎麼做。我不知道是否有什麼錯誤讓它運行時間超過1.5秒?

- (void)decreaseProgress { 
    if (currentProgress > 0.0000f) { 
     currentProgress -= 0.001f; 
     [_timeLineProgress setProgress:currentProgress animated:YES]; 

     [self performSelector:@selector(decreaseProgress) withObject:self afterDelay:0.0015 inModes:@[NSDefaultRunLoopMode]]; 
    } else { 
     [self stopTimer]; 
    } 
} 
+0

您應該使用一個NSTimer來代替,而立足於實際經過的時間進度。 – rmaddy

+0

@rmaddy會有什麼重大分歧嗎?因爲我確實使用了NSTimer,但仍然遇到同樣的問題。 – JozackOverFlow

+0

這就是爲什麼進度需要基於實際經過的時間而不是一些遞增的值。 – rmaddy

回答

1

您正試圖在1.5秒內更新進度視圖1000次。這太快了,因爲屏幕每秒只更新60次。換句話說,每次在屏幕上實際重繪進度條時,都會更新進度條10次以上。

相反,我會建議以0.1秒的間隔更新15次,並且每次更改進度條1/15。

檢查代碼執行情況的一種方法是使用CACurrentMediaTime函數獲取時間戳。這裏有一些示例代碼演示瞭如何做到這一點。變量progressStart是發生按鈕按下事件時的時間戳,並且NSLog顯示相對於開始時間逝去的時間量。

該代碼的一個重要功能是在updateProgress方法中儘可能早地調用performSelector方法以儘量減少滑動。

@interface ViewController() 
{ 
    CFTimeInterval progressStart; 
    int progressCount; 
} 
@property (weak, nonatomic) IBOutlet UIProgressView *progressView; 
@end 

- (void)updateProgress 
{ 
    if (progressCount > 0) 
     [self performSelector:@selector(updateProgress) withObject:nil afterDelay:0.1]; 

    self.progressView.progress = progressCount/15.0; 
    NSLog(@"%2d %.3lf", progressCount, CACurrentMediaTime() - progressStart); 
    progressCount--; 
} 

- (IBAction)someButtonPressed 
{ 
    self.progressView.progress = 1.0; 
    progressStart = CACurrentMediaTime(); 
    progressCount = 15; 
    [self updateProgress]; 
} 

這裏是從一個典型的運行

2015-07-01 13:05:57.610 Progress[8354:907] 15 0.000 
2015-07-01 13:05:57.711 Progress[8354:907] 14 0.101 
2015-07-01 13:05:57.813 Progress[8354:907] 13 0.203 
2015-07-01 13:05:57.914 Progress[8354:907] 12 0.304 
2015-07-01 13:05:58.015 Progress[8354:907] 11 0.405 
2015-07-01 13:05:58.116 Progress[8354:907] 10 0.506 
2015-07-01 13:05:58.218 Progress[8354:907] 9 0.608 
2015-07-01 13:05:58.319 Progress[8354:907] 8 0.709 
2015-07-01 13:05:58.420 Progress[8354:907] 7 0.810 
2015-07-01 13:05:58.520 Progress[8354:907] 6 0.910 
2015-07-01 13:05:58.621 Progress[8354:907] 5 1.011 
2015-07-01 13:05:58.722 Progress[8354:907] 4 1.112 
2015-07-01 13:05:58.823 Progress[8354:907] 3 1.213 
2015-07-01 13:05:58.924 Progress[8354:907] 2 1.314 
2015-07-01 13:05:59.024 Progress[8354:907] 1 1.415 
2015-07-01 13:05:59.125 Progress[8354:907] 0 1.515 

注意,方法有大約1毫秒每個事件滑移的結果。總滑移是15毫秒。設備屏幕更新率爲60幀/秒,即16.7毫秒/幀。因此,總滑動時間少於一幀時間,並且不會被用戶注意到。

正如rmaddy在評論中指出的那樣,使用NSTimer可以避免大部分的滑動。但是,最後的計時器事件仍然可能會以任意的時間間隔滑動。

+0

感謝您的回覆,我只是嘗試了您的建議,但進度條仍然在2秒內運行。我不知道爲什麼? – JozackOverFlow

+1

這取決於系統在做什麼。 'performSelector:afterDelay'方法只指定最小延遲。如果系統繁忙,實際的延遲可能會更長。 – user3386109

+0

那麼沒有辦法讓它運行1.5秒? – JozackOverFlow

3

設置動畫的進度,試試這個代碼在你decreaseProgress方法

[UIView animateWithDuration:1.5 animations:^{ 
     [_timeLineProgress setProgress:0.0 animated:YES]; 
    }]; 
+0

感謝您的解決方案Vinay。我認爲這是可行的,但在進度正在運行時,我還有其他一些行動,這樣它可以順利進行動畫製作,但我不會全面控制它,例如在運行時重置進度。 – JozackOverFlow