使用CGContext绘制时的动画

时间:2013-08-19 22:40:54

标签: ios objective-c animation uiview cgcontext

我的问题是如何使用CGContextRef绘图时为绘图过程设置动画。可能吗?假设是,怎么样?

我有两个我想要动画的代码片段。第一个绘制一个进度条,第二个绘制一个简单的折线图。绘图在UIView

的子类中完成

进度条很简单。但我希望它能从左边抽出来。我很确定这需要使用UIRectFill之外的其他内容,但我不知道如何实现它。

- (void)drawProgressLine
{
    [bgColor set];
    UIRectFill(self.bounds);
    [graphColor set];
    UIRectFill(CGRectMake(0, 0, self.frame.size.width / 100 * [[items objectAtIndex:0] floatValue], self.frame.size.height));
}

折线图有点复杂。我真的很喜欢它从左边开始逐渐向右边逐渐画出自己,但是如果那个太多了我怎么能慢慢淡入呢?代码:

- (void)drawLineChart
{
    [bgColor set];
    UIRectFill(self.bounds);
    [graphColor set];

    if (items.count < 2) return;

    CGRect bounds = CGRectMake(0, 50, self.bounds.size.width, self.bounds.size.height - 100);

    float max = -1;
    for (GraphItem *item in items)
        if (item.value > max)
            max = item.value;

    float xStep = (self.frame.size.width) / (items.count - 1);

    for (int i = 0; i < items.count; i++)
    {
        if (i == items.count - 1) break;

        float itemHeight = bounds.origin.y + bounds.size.height - ((GraphItem*)[items objectAtIndex:i]).value / max * bounds.size.height;
        float nextItemHeight = bounds.origin.y + bounds.size.height - ((GraphItem*)[items objectAtIndex:i + 1]).value / max * bounds.size.height;
        CGPoint start = CGPointMake(xStep * i, itemHeight);
        CGPoint stop = CGPointMake(xStep * (i + 1), nextItemHeight);
        [self drawLineFromPoint:start toPoint:stop lineWidth:1 color:graphColor shadow:YES];
    }
}

我猜很简单。如果重要,drawLineFromPoint.....的实现方式如下:

- (void)drawLineFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint lineWidth:(CGFloat)width color:(UIColor *)color shadow:(BOOL)shadow
{
    if (shadow)
    {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGFloat components[4] = {0.0, 0.0, 0.0, 1.0};
        CGColorRef shadowColor = CGColorCreate(colorSpace, components);
        CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(1,1), 2.0, shadowColor);
    }

    CGContextBeginPath(context);
    CGContextSetLineWidth(context, width);
    CGContextMoveToPoint(context, startPoint.x, startPoint.y);
    CGContextAddLineToPoint(context, endPoint.x, endPoint.y);
    CGContextClosePath(context);
    [color setStroke];
    CGContextStrokePath(context);
    CGContextSetShadowWithColor(context, CGSizeZero, 0, NULL);
}

我希望自己明确表示,因为我的国家凌晨1点,这篇文章是我和我床之间的最后一件事。干杯,Jan。

2 个答案:

答案 0 :(得分:3)

听起来你不理解UIKit view drawing cycle。您是否了解每次要更改自定义绘制视图的外观时,都需要发送setNeedsDisplay?然后你需要在你的drawRect:方法中完全重绘它?在drawRect:返回之前,您的绘图不会出现在屏幕上,之后您无法在该视图中绘制更多内容,直到它收到另一条drawRect:消息。如果您想要对视图的内容进行动画处理,则需要定期向视图发送setNeedsDisplay(例如,每隔1/30或1/60秒,使用NSTimer或一个CADisplayLink)。

答案 1 :(得分:2)

好像你处理了进度条,所以这就是我对图形绘制的建议。只需创建并调试一次代码即可绘制整个图形。然后,使用一个剪辑矩形来设置宽度,使剪辑矩形开始变粗,然后在宽度上延伸,直到整个图形变得可见(从左到右)。这将使用户知道你所拥有的任何一行都是从左到右“绘制”,但实际的代码非常简单,因为动画步骤只是修改了一个矩形,使每个“步”更宽。有关CoreGraphics调用的更多信息,请参阅此问题:How to set up a clipping rectangle or area