我正在尝试创建一个加载屏幕,在我的应用发出网络请求时绘制一个圆圈。圆圈的绘制量表示请求与完成的接近程度。但是,网络请求和动画之间存在严重的延迟(约8秒)。经过大量的搜索后,我没有找到任何有这个问题的人,所以我非常绝望。
我现在的设置是,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];
});
}
答案 0 :(得分:1)
我遇到了同样的问题。这似乎是由后台线程设置路径引起的。确保在主线程上发生这种情况解决了问题。现在立即更新形状。