2

我的问题是如何在使用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 点,这篇文章是我和我的床之间的最后一件事。干杯,简。

4

2 回答 2

3

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

于 2013-08-20T03:47:19.733 回答
2

看起来你已经处理了进度条,所以这是我对图表绘制的建议。只需创建和调试一次代码即可绘制整个图形。然后,使用您为其宽度设置动画的剪辑矩形,以便剪辑矩形开始时很窄,然后在宽度上延伸,直到整个图形变得可见(从左到右)。这会让用户觉得无论你有什么线条都是从左到右“绘制”的,但实际代码非常简单,因为动画步骤只是修改剪辑矩形以使其每个“步骤”更宽。有关 CoreGraphics 调用的更多信息,请参阅此问题:如何设置剪切矩形或区域

于 2013-08-20T03:37:51.630 回答