【问题标题】:Animation when drawing with CGContext使用 CGContext 绘制时的动画
【发布时间】:2013-08-19 22:40:54
【问题描述】:

我的问题是如何在使用CGContextRef 绘制时为绘制过程设置动画。是否可以?假设是,如何?

我有两个要制作动画的代码 sn-ps。第一个绘制进度条,第二个绘制简单的折线图。绘图是在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 点,这篇文章是我和我的床之间的最后一件事。干杯,一月。

【问题讨论】:

    标签: ios objective-c animation uiview cgcontext


    【解决方案1】:

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

    【讨论】:

    • 我确实了解setNeedsDisplay 的工作原理,我通过drawRect 进行上述绘图,但它会在一瞬间在视图上绘制整个图形。如上所述,我想做得又好又容易。然而,我确实遇到了一个有趣但不完整的解决方案,我使用 view.frame = CGRectZero; [UIView animateWithDuration:0.5f animations:^(void){view.frame = fullFrame;}]; 这有点符合我的要求。问题是视图位于 tableview 内,每次单元格出现在屏幕上时它都会被动画化,我希望它只在第一次动画化。有什么想法吗?
    【解决方案2】:

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

    【讨论】:

    • 处理过是什么意思?它没有动画它只是出现。我看到在这个剪辑中可能有一些“有用的潜力”:) 你能否通过编写一个从左到右增长的动画进度条的例子来扩展?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多