我正在嘗試創建一個加載屏幕,在我的應用程序發出網絡請求時繪製一個圓圈。圈的數量意味着表示請求的完成程度。但是,網絡請求和動畫之間存在嚴重的延遲(約8秒)。經過大量的搜索之後,我還沒有發現任何有過這個問題的人,所以我非常絕望。CAShapeLayer路徑動畫有嚴重延遲
我現在的設置是,一個NSProgress對象會隨着請求被更新而更新,並且會觸發userInfo中NSProgress對象的KVO通知。這與here發現的方法相同。
#Client.m
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
NSProgress *progress = (NSProgress *)object;
NSDictionary *userInfo = @{@"progress":progress};
[[NSNotificationCenter defaultCenter] postNotificationName:@"FractionCompleted" object:self userInfo:userInfo];
}
}
然後被監聽通知將更新與NSProgress的fractionCompleted的LoadingProgressView視圖控制器對象,它接收。現在
#MainViewController.m
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateProgress:) name:@"FractionCompleted" object:nil];
...
...
- (void)updateProgress:(NSNotification*)note {
NSProgress* prog = note.userInfo[@"progress"];
[self.progressIndicatorView updateProgress:(CGFloat)prog.fractionCompleted];
}
的LoadingProgressView內,該CAShapeLayer的strokeEnd屬性設置爲fractionCompleted值。我正在使用來自發現here的教程的相同想法。
#LoadingProgressView.m
- (void)updateProgress:(CGFloat)frac {
_circlePathLayer.strokeEnd = frac;
}
當我實際發出請求時,在請求完成後大約5秒後沒有任何反應。在那一刻,整個圓圈就會立即生成動畫。
我絕對沒有想法爲什麼會發生這種情況,這讓我發瘋。我可以清楚地看到使用調試器實時更新strokeEnd屬性,然而LoadingProgressView拒絕重新渲染,直到很久以後。很感謝任何形式的幫助。謝謝。
編輯:好的,所以臨時解決方案是推遲一個新的線程延遲0更新每個通知的進度視圖。然而,這似乎是可憐的線程管理,因爲我可以創建超過一百個不同的線程來完成相同的任務。我想知道是否還有其他事情可以做。
- (void)updateProgress:(NSNotification*)note {
NSProgress* prog = note.userInfo[@"progress"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.progressIndicatorView updateProgress:(CGFloat)prog.fractionCompleted];
});
}
'dispatch_after'不會創建(或'fork')一個新的線程 - 它只是在指定的隊列上運行一個塊。傳遞'dispatch_get_main_queue()'將在主線程中有效地運行該塊。 – Losiowaty
此外,從主線程更新外界的UI是不會工作的:) – Losiowaty
哈哈哦,好的謝謝你的信息。你介意解釋這裏發生了什麼,爲什麼我必須首先做這件事? – blzn