如何在drawRect中为用CGContextDrawPath等绘制的路径设置动画填充颜色?

如何在drawRect中为用CGContextDrawPath等绘制的路径设置动画填充颜色?

问题描述:

我想知道是否可以对使用CoreGraphics绘制的路径的填充颜色进行动画处理?
我正在绘制:
使用Quartz进行简单绘制-核心图形

I wonder if is possible to animate the fill color of a path I have drawn using CoreGraphics? I am drawing this: Simple drawing with Quartz - Core Graphics

,我想将其填充颜色从白色更改为灰色。
这可能吗?

and I want to change its fill color from white to let's say gray. Is this possible?

我知道view.layer.content属性的存在,但这在这里有用吗?不过,我不确定在这种情况下如何使用它。

I know the existence of view.layer.content property but Is this useful here? Though, I am not sure how can I use it in this case.

预先感谢。

更新

我正在尝试这种方法(因为它有故障,所以我可以判断它是否可以正常工作)
CGImageRef并使用UIView动画将其传递给self.layer.contents,这是可动画的
,但是....除了没有动画之外,我得到的结果很奇怪。

I am trying this approach (its buggy, hence I can tell if its going to work) basically I am creating a CGImageRef and pass it to self.layer.contents which is animatable using UIView animations but .... I am getting strange results, besides is not animating.

int bitsPerComponent = 8;
int channels = 4;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *data = malloc(self.bounds.size.width*self.bounds.size.height*channels);

CGContextRef context = CGBitmapContextCreate(data,                      //pointer to data
                                             self.bounds.size.width,    //width
                                             self.bounds.size.height,   //height
                                             bitsPerComponent,          //bitsPerComponent
                                             self.bounds.size.width*channels,//bytesPerRow
                                             colorSpace,                    //colorSpace
                                             kCGImageAlphaPremultipliedFirst);  //bitmapInfo

//method that uses below link's code
[self _drawBackgroundInContext:context color:UIColorFromMandalaBoxType(type)];

CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL,         //info, NULL
                                                              data,         //pointer to data
                                                              self.bounds.size.width*self.bounds.size.height*channels, //number of bytes
                                                              NULL);        //release callback


CGImageRef image = CGImageCreate(self.bounds.size.width,            //width
                                 self.bounds.size.height,         //height
                                 bitsPerComponent,                //bitsPerComponent
                                 bitsPerComponent*channels,       //bitsPerPixel
                                 self.bounds.size.width*channels, //bytesPerRow
                                 colorSpace,                        //colorSpace
                                 kCGImageAlphaPremultipliedFirst,   //bitmapInfo
                                 dataProvider, NULL, false, kCGRenderingIntentDefault);

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.5f];
self.layer.contents = (id)image;
[UIView commitAnimations];

CGImageRelease(image);
CGDataProviderRelease(dataProvider);
CGContextRelease(context);
free(data);
CGColorSpaceRelease(colorSpace);

逻辑还可以吗?这里的错误在哪里? ;(

Is logic OK?, and where is the mistake here? ;(

已编辑答案:

您无法设置动画在 -drawRect:中。如果要为形状的颜色设置动画,则可能需要查看 CAShapeLayer 。它允许您指定应绘制的 CGPathRef 以及笔触/填充颜色,并且所有这些属性都是可设置动画的。 ,这并不是说它的工作效率非常高。如果您的形状并非一直都在制作动画,则可能需要将 shouldRasterize 设置为 YES 。只要图层不设置动画,这将显着加快渲染速度。如果这样做,请小心,因为存在与 shouldRasterize 相关的错误>。我想到的一个问题是,如果将 opacity 设置为0,然后将其设置为非0,则 shouldRasterize 倾向于完全不绘制任何图形,因为它以0不透明度缓存了图形。

Edited answer:
You can't animate stuff in -drawRect:. If you're trying to animate the color of a shape, you may want to look at CAShapeLayer. It allows you to specify a CGPathRef that it should draw, as well as stroke/fill colors, and all these properties are animatable. One thing to bear in mind, though, is that this isn't terribly efficient at its job. If your shape is not animating all the time, you may want to set shouldRasterize to YES. This will significantly speed up the rendering as long as the layer is not animating. If you do this, be careful as there are bugs relating to shouldRasterize. One that springs to mind is if you set the opacity to 0, and later make it non-0, shouldRasterize has a tendency to draw nothing at all because it cached the drawing at the 0 opacity.

原始l回答

如果您完全生活在CoreGraphics中,则可以使用 CGContextSetFillColorWithColor(),为其提供上下文和CGColorRef (例如 CGContextSetFillColorWithColor(ctx,[UIColor grayColor] .CGColor)。如果要调整当前图形上下文的填充颜色,也可以只使用稍微简单些的 [[UIColor grayColor] setFill]

Original answer:
If you're living in CoreGraphics entirely, you can use CGContextSetFillColorWithColor(), giving it the context and a CGColorRef (e.g. CGContextSetFillColorWithColor(ctx, [UIColor grayColor].CGColor). If you're trying to adjust the fill color of the "current" graphics context, you can also just use the slightly simpler [[UIColor grayColor] setFill].

编辑:查看链接后,只需更改显示以下内容的行

Edit: After looking at your link, you just need to change the line that says

CGContextSetFillColorWithColor(context, [UIColor white].CGColor);

使用所需的任何颜色。在这种情况下,将是

to use whatever color you want. In this case it would be

CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor);