1

I'm trying to animate a bezier curve I made with Paintcode (great app, btw) and am drawing in a custom UIView in the "drawRect" method.

The drawing works fine but I want to animate a single point in the bezier curve.

Here's my non-working method:

-(void)animateFlame{
    NSLog(@"Animating");
    // Create the starting path. Your curved line.
    //UIBezierPath * startPath;
    // Create the end path. Your straight line.
    //UIBezierPath * endPath = [self generateFlame];
    //[endPath moveToPoint: CGPointMake(167.47, 214)];

    int displacementX = (((int)arc4random()%50))-25;
    int displacementY = (((int)arc4random()%30))-15;
    NSLog(@"%i %i",displacementX,displacementY);

    UIBezierPath* theBezierPath = [UIBezierPath bezierPath];
    [theBezierPath moveToPoint: CGPointMake(167.47, 214)];
    [theBezierPath addCurveToPoint: CGPointMake(181+displacementX, 100+displacementY) controlPoint1: CGPointMake(89.74, 214) controlPoint2: CGPointMake(192.78+displacementX, 76.52+displacementY)];
    [theBezierPath addCurveToPoint: CGPointMake(167.47, 214) controlPoint1: CGPointMake(169.22+displacementX, 123.48+displacementY) controlPoint2: CGPointMake(245.2, 214)];
    [theBezierPath closePath];
    // Create the shape layer to display and animate the line.
    CAShapeLayer * myLineShapeLayer = [[CAShapeLayer alloc] init];

    CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
    pathAnimation.fromValue = (__bridge id)[bezierPath CGPath];
    pathAnimation.toValue = (__bridge id)[theBezierPath CGPath];
    pathAnimation.duration = 0.39f;
    [myLineShapeLayer addAnimation:pathAnimation forKey:@"pathAnimation"];

    bezierPath = theBezierPath;
}

Using this, nothing moves on the screen at all. The random displacements generated are good and the bezierPath variable is a UIBezierPath that's declared with a class scope.

Am I missing something? (The goal is to do a sort of candle-like animation)

4

1 回答 1

3

快速编辑 刚刚看到你的图层代码。你混淆了几个不同的概念。像drawRect、CAShapeLayer、旧动画代码等...

通过执行以下方法,您应该能够使其正常工作。

你不能这样做:(你不能为drawRect的内容设置动画(即你不能让它在动画过程中多次绘制)。

您也许可以使用计时器或其他东西并创建自己的动画类型代码。(即创建一个每秒触发 30 次的计时器并运行一个函数来计算您在动画中的位置并更新您想要更改的值并调用[self setNeedsDisplay];以触发 draw rect 方法。

除此之外,你无能为力。

另一个编辑

只是在这里添加另一个选项。使用 CAShapeLayer 执行此操作可能性能很差。您最好使用带有一系列 UIImage 的 UIImageView。

UIImageView上有内置的属性,animationImages,animationDuration等。

可能的解决方案

path属性CAShapeLayer是可动画的,因此您可以使用它。

就像是...

// set up properties for path
@property (nonatomic, assign) CGPath startPath;
@property (nonatomic, assign) CGPath endPath;
@property (nonatomic, strong) CAShapeLayer *pathLayer;

// create the startPath
UIBezierPath *path = [UIBezierPath //create your path using the paint code code
self.startPath = path.CGPath;

// create the end path
path = [UIBezierPath //create your path using the paint code code
self.endPath = path.CGPath;

// create the shapee layer
self.pathLayer = [CAShapeLayer layer];
self.pathLayer.path = self.startPath;
//also set line width, colour, shadows, etc...

[self.view.layer addSubLayer:self.pathLayer];

然后你应该能够像这样为路径设置动画......

- (void)animatePath
{
    [UIView animateWithDuration:2.0
        animations^() {
            self.pathlayer.path = self.endPath;
    }];
}

文档中有很多关于 CAShapeLayer 和动画路径属性的注释。

不过,这应该可行。

此外,摆脱旧的动画代码。自 iOS4.3 以来它已经消失了,您应该使用更新的块动画。

于 2014-01-28T18:08:11.700 回答