Анимация формы с помощью CoreAnimation

Я приближаюсь к основной анимации и рисую эмпирически. Я пытаюсь оживить простую форму; форма, о которой идет речь, формируется тремя линиями плюс кривая Безье. Также выводится красная линия, чтобы отображать контрольные точки кривой.

alt text http://img.skitch.com/20091119-1ufar435jdq7nwh8pid5cb6kmm.jpg

Мой главный контроллер просто добавляет это подзапрос и вызывает метод adjustWave всякий раз, когда touchesEnd. Вот код для моего класса рисования фигуры. Как вы видите, у класса есть одно свойство, cp1x (x контрольной точки безье 1). Это значение, которое я хотел бы оживить. Разум, это глупая попытка...

- (void)drawRect:(CGRect)rect {
    float cp1y = 230.0f;
    float cp2x = 100.0f;
    float cp2y = 120.0f;

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGContextClearRect(ctx, rect);

    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path, NULL, 10.0f, 200.0f); 
    CGPathAddCurveToPoint (path, NULL, cp1x, cp1y, cp2x, cp2y, 300.0f, 200.0f);
    CGPathAddLineToPoint(path, NULL, 300.0f, 300.0f); 
    CGPathAddLineToPoint(path, NULL, 10.0f, 300.0f); 
    CGPathCloseSubpath(path); 
    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor); 
    CGContextAddPath(ctx, path); 
    CGContextFillPath(ctx);

    // Drawing a line from control points 1 and 2
    CGContextBeginPath(ctx);
    CGContextSetRGBStrokeColor(ctx,1,0,0,1);
    CGMutablePathRef cp1 = CGPathCreateMutable(); 
    CGPathMoveToPoint(cp1, NULL, cp1x, cp1y); 
    CGPathAddLineToPoint(cp1, NULL, cp2x, cp2y); 
    CGPathCloseSubpath(cp1); 
    CGContextAddPath(ctx, cp1); 
    CGContextStrokePath(ctx);
}

- (void)adjustWave {
    [UIView beginAnimations:@"movement" context:nil]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationWillStartSelector:@selector(didStart:context:)]; 
    [UIView setAnimationDidStopSelector:@selector(didStop:finished:context:)]; 
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    [UIView setAnimationDuration:3.0f]; 
    [UIView setAnimationRepeatCount:3]; 
    [UIView setAnimationRepeatAutoreverses:YES]; 
    cp1x = cp1x + 20.0f;
    [UIView commitAnimations];
}

Форма не изменяется. Если, наоборот, я вынимаю код ЦС и добавляю простой `[self setNeedsDisplay] в последнем методе, который изменяет форма, но явно без CA. Можете ли вы помочь sme? Я уверен, что здесь делаю очень большую ошибку... Заранее спасибо, Davide

Ответ 1

Если вы пишете это для iPhone OS 3.x(или Snow Leopard), новый класс CAShapeLayer должен позволить вам делать такие анимация довольно легко. Если у вас есть путь, который поддерживает одинаковое количество контрольных точек (например, в вашем случае), вы можете установить этот путь к CAShapeLayer, а затем анимировать свойство пути от этого начального значения до вашего конечного пути. Core Animation выполнит соответствующую интерполяцию контрольных точек на пути для анимации между этими двумя состояниями (более того, если вы используете CAKeyframeAnimation).

Обратите внимание, что это слой, поэтому вам нужно добавить его в качестве подуровня вашего UIView. Кроме того, я не считаю, что свойство path неявно анимируется, поэтому вам может понадобиться вручную создать CABasicAnimation для анимации изменения формы от пути 1 до пути 2.

EDIT (11/21/2009): Джо Рисиоппо имеет приятную запись о CAShapeLayer здесь, включая некоторые видеоролики, которые показывают эти виды анимации.

Ответ 2

Вы не сможете анимировать свою фигуру с помощью CA. Вы можете анимировать свойства слоя в CA, а не пользовательские свойства.

CA может быть быстрым, потому что ему не нужно возвращаться к вашему коду для выполнения анимаций, если вы думаете о том, как он реализован, он в основном представляет собой поток, выполняющий операции примитивов GL с кадрами и содержимым CALayer.

CA-анимации - это наборы инструкций для CA, которые будут запускаться в фоновом потоке, запускать и забывать (плюс обратный вызов при завершении анимации), а не обратные вызовы к вашему коду.

Анимация содержимого слоя потребует, чтобы CA перезвонил вам, чтобы рисовать в каждом кадре, или дать вам указание CA о том, как рисовать. Ни один из них не происходит.