如何正确使用DrawRect

时间:2013-06-04 17:00:27

标签: ios objective-c cocoa-touch uikit core-animation

我正在构建自定义UIActivityIndicator。为此,我创建了以下draw rect函数:

-(void) drawRect:(CGRect)rect  
{
CGPoint point;
NSLog(@"here %d",stage);`

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 2.0);

for (int i = 1 ; i<=10; ++i) {


    CGContextSetStrokeColorWithColor(ctx, [[self getColorForStage:stage+i WithAlpha:0.1 *i] CGColor]);
    point = [self pointOnOuterCirecleWithAngel:stage+i];
    CGContextMoveToPoint(ctx, point.x, point.y);
    point = [self pointOnInnerCirecleWithAngel:stage+i];
    CGContextAddLineToPoint( ctx, point.x, point.y);
    CGContextStrokePath(ctx);
}



stage++;
}

我添加了NSTimer来致电[self setNeedsDisplay];

动画工作正常,但每次我将它滚动到我的应用程序时,我会滚动一个表格或做任何动画将停止直到桌子停止移动。

我假设只有在UI完成更新后才更新我的DrawRect但我该如何解决它或以正确的方式做到

3 个答案:

答案 0 :(得分:3)

如果要在桌面视图(或任何其他滚动视图)滚动时触发,则必须使用不同的runloop模式手动安排计时器。默认情况下,滚动时定时器不会触发以提高性能。

NSTimer *timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

(您将获得NSDefaultRunLoopMode而非NSRunLoopCommonModes的默认行为。)

答案 1 :(得分:1)

你不应该致电[self setNeedsDisplay]; 在视图didload

中执行

答案 2 :(得分:0)

如果您描述了您想要的结果,那将会有所帮助。从查看代码看起来你正试图获得一个多色环。你指的是动画,但这里没有真正的动画。它可能看起来很动画,基于让它以一定间隔重绘,但我不确定它是如何发生的。如果它每次重绘完全相同的东西,你将看不到任何看起来像运动的东西。每次处理drawRect时,您调用的方法(getColorForStagepointOnOuterCirecleWithAngel)是否会为相同的参数返回不同的结果?

您不应该使用drawRect来实现动画。 drawRect应该使你的视图看起来像它应该看起来,然后再做任何事情,直到它再次需要。除非视图被隐藏并且操作系统回收了保持其像素的内存,否则通常不需要再次调用它。 setNeedsDisplay的目的是触发再次调用drawRect,因为视图表示的信息已更改,而不是更新相同数据的正在进行的动画。您可以通过多种方式更改视图的外观,这些方式不涉及再次运行drawRect,例如更改其大小,位置,alpha或旋转它。

如果在平移和缩放过程中没有调用drawRect,我会不会感到惊讶,并且在调整视图之后,对setNeedsDisplay的调用会排队。

您应该使用Core Animation。希望Core Animation在平移和缩放过程中继续运行。您应该能够通过一次调用drawRect然后使用Core Animation旋转它来绘制图标来实现所需的效果。