您正試圖在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
可以避免大部分的滑動。但是,最後的計時器事件仍然可能會以任意的時間間隔滑動。
您應該使用一個NSTimer來代替,而立足於實際經過的時間進度。 – rmaddy
@rmaddy會有什麼重大分歧嗎?因爲我確實使用了NSTimer,但仍然遇到同樣的問題。 – JozackOverFlow
這就是爲什麼進度需要基於實際經過的時間而不是一些遞增的值。 – rmaddy