0

我正在尝试设置自定义 UIView 类的背景颜色。该类还在drawRect:方法中进行石英绘图。

由于在视图的下一次重绘之前不会发生背景颜色更改,因此我backgroundColor在调用之前更改了 UIView 的属性setNeedsDisplay。在视图重绘时,我设置了UIActivityIndicatorView动画。

self.backgroundColor = theColor; 
[indicator startAnimating];
[self performSelectorInBackground:@selector(setNeedsDisplay) withObject:nil];

指示器在 结束时停止setNeedsDisplaytheColor每次我需要调用它时都会改变。

假设我有一个耗时的setNeedsDisplay过程。我想设置背景并保留指示器动画。目前,更改backgroundColor调用setNeedsDisplay但在方法运行之前甚至不会更改背景performSelectorInBackground颜色!因此,我的应用程序挂起,并且没有任何指标动画。我该如何处理这个排序问题?谢谢。

编辑:我的意思是我的drawrect:可能很耗时。

4

2 回答 2

4

Let's say I have a time consuming setNeedsDisplay process

Let's not. You have no business overriding setNeedsDisplay. I am not at all clear on what you're ultimately trying to accomplish but this entire question seems to be a misunderstanding of how to draw. When you call setNeedsDisplay (which, as you've been told, you must do in the main thread), that's that; you stand out of the way, and when the redraw moment comes, your view's drawRect: is called. That's drawing.

If the problem is simply that the activity indicator never gets going, that's because you never give it a chance. It too is not going to start going until the redraw moment. But you are stopping the activity indicator before the redraw moment even comes! So obviously you'll never see it go.

The way to start an activity indicator visibly before the next thing you do is to step out to the main thread after the next redraw moment. This is called "delayed performance". Example:

self.backgroundColor = theColor; 
[indicator startAnimating];
double delayInSeconds = 0.1;
dispatch_time_t popTime =
    dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    // do something further, e.g. call setNeedsDisplay
};

You could extend that example by calling dispatch_after yet again to stop the indicator after the next redraw moment.

I must impress upon you, however, that if the mere act of drawing takes so long that you need an activity indicator to cover it, you're drawing wrong. Your act of drawing must be very very fast. You might want to watch the WWDC 2012 video on this very topic; it gives excellent tips on how to draw efficiently.

于 2013-02-24T01:07:30.370 回答
0

您只能在主线程上更新 UI,而不是在背景中

尝试使用另一个带有活动指示器的子视图,在重绘之前放入并在之后从超级视图中删除

于 2013-02-24T00:29:39.117 回答