2015-08-27 73 views
0

我正在尝试创建一个加载屏幕,在我的应用程序发出网络请求时绘制一个圆圈。圈的数量意味着表示请求的完成程度。但是,网络请求和动画之间存在严重的延迟(约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]; 
    }); 
} 
+0

'dispatch_after'不会创建(或'fork')一个新的线程 - 它只是在指定的队列上运行一个块。传递'dispatch_get_main_queue()'将在主线程中有效地运行该块。 – Losiowaty

+0

此外,从主线程更新外界的UI是不会工作的:) – Losiowaty

+0

哈哈哦,好的谢谢你的信息。你介意解释这里发生了什么,为什么我必须首先做这件事? – blzn

回答

1

我遇到了同样的问题。这似乎是由后台线程设置路径引起的。确保主线程发生这种情况,解决了问题。现在更新形状立即绘制。

+1

虽然这个答案看起来是正确的,或者至少在正确的轨道上,您能否提供更多的信息和一些代码来澄清? – SomethingOn

+0

@ s1m0nw1:这不是一个不同的问题 – ExDev