6

我正在创建一个简单的应用程序,当用户按下按钮时,将在屏幕上绘制一系列线条,用户将能够实时看到这些线条(几乎就像动画一样)。

我的代码看起来像这样(已简化):

UIGraphicsBeginImageContext(CGSizeMake(300,300));
CGContextRef context = UIGraphicsGetCurrentContext();

for (int i = 0; i < 100; i++ ) {
    CGContextMoveToPoint(context, i, i);
    CGContextAddLineToPoint(context, i+20, i+20);
    CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
    CGContextStrokePath(context);
}

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

我的问题是:

1) 一旦用户按下按钮,UIThread 就会阻塞,直到绘制完成。

2)我无法一次在屏幕上绘制一条线 - 我尝试直接在循环内设置 UIImage 并尝试在循环内设置图层内容。

我该如何解决这些问题?

4

1 回答 1

16

你说“就像动画一样”。为什么不做一个真正的动画,比如 Core Graphics CABasicAnimation?您真的需要将其显示为一系列线条,还是适当的动画可以?

如果您想为线条的实际绘制设置动画,您可以执行以下操作:

#import <QuartzCore/QuartzCore.h>

- (void)drawBezierAnimate:(BOOL)animate
{
    UIBezierPath *bezierPath = [self bezierPath];

    CAShapeLayer *bezier = [[CAShapeLayer alloc] init];

    bezier.path          = bezierPath.CGPath;
    bezier.strokeColor   = [UIColor blueColor].CGColor;
    bezier.fillColor     = [UIColor clearColor].CGColor;
    bezier.lineWidth     = 5.0;
    bezier.strokeStart   = 0.0;
    bezier.strokeEnd     = 1.0;
    [self.view.layer addSublayer:bezier];

    if (animate)
    {
        CABasicAnimation *animateStrokeEnd = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        animateStrokeEnd.duration  = 10.0;
        animateStrokeEnd.fromValue = [NSNumber numberWithFloat:0.0f];
        animateStrokeEnd.toValue   = [NSNumber numberWithFloat:1.0f];
        [bezier addAnimation:animateStrokeEnd forKey:@"strokeEndAnimation"];
    }
}

然后你所要做的就是UIBezierPath为你的线路创建,例如:

- (UIBezierPath *)bezierPath
{
    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(0.0, 0.0)];

    [path addLineToPoint:CGPointMake(200.0, 200.0)];

    return path;
}

如果你愿意,你可以将一堆线拼凑成一条路径,例如这里是一个大致正弦曲线形状的线系列:

- (UIBezierPath *)bezierPath
{
    UIBezierPath *path = [UIBezierPath bezierPath];
    CGPoint point = self.view.center;

    [path moveToPoint:CGPointMake(0, self.view.frame.size.height / 2.0)];

    for (CGFloat f = 0.0; f < M_PI * 2; f += 0.75)
    {
        point = CGPointMake(f / (M_PI * 2) * self.view.frame.size.width, sinf(f) * 200.0 + self.view.frame.size.height / 2.0);
        [path addLineToPoint:point];
    }

    return path;
}

而且这些不会阻塞主线程。

顺便说一句,您显然必须在CoreGraphics.framework目标的Build Settings下方添加Link Binary With Libraries

于 2012-10-10T03:33:51.743 回答