Офигеть с анимационной цепочкой XCode - PullRequest
1 голос
/ 30 июня 2010

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

Как опубликовано здесь: Вращение вокруг диагональной оси

Я пытался воссоздать фигуру "Реверси" - квадрат, который при активации вращался бы вокруг оси Y = X, и менял цвет, чтобы датьиллюзия, что он вращается, чтобы показать свою спину.Итак, синий с одной стороны, красный с другой.

Чтобы сделать эту работу, мне пришлось разбить анимацию на 4 части: 1) Повернуть на 90 градусов вокруг Y = X 2) Изменить цвет со oldColorдо 0,5 * oldColor (создавая иллюзию затемнения) 3) Поверните на 90 градусов вокруг Y = X (переведите «заднюю» сторону лицом вперед) 4) Измените цвет с 0,5 * newColor на newColor (создавая иллюзию освещения какчасть выходит больше на свет)

Это работает просто отлично ... в теории.Проблема в том, что первые два шага выполняются чудесным образом, но я не могу запустить второй два.

Я пытался сделать это в CAAnimationGroup, но проблема в том, что мне нужно явно установить цвет нановый цвет, или же когда начинается анимация шагов 3 и 4, появляется вспышка для исходного цвета.Я не мог понять, как это сделать в группе, поэтому я разбил их на отдельные анимации и просто связал их в цепочку следующим образом: 1) Огонь 1 и 2 2) Поймай событие animationDidStop: закончено: и установи цвет, затем запусти 3 и 4

При этом 3 и 4 никогда не стреляют.Он просто зависает.

Так что я попытался изменить timeOffset на 3 & 4, чтобы он был продолжительностью анимации 1 & 2.Это привело к тому, что 1 и 2 не запускаются, а 3 и 4 работают прекрасно ... ARG!

Here is the code broken out as individual animations:
<pre><code>
- (IBAction)handleButtonClick {
 FlipLayer3View *v = (FlipLayer3View *)[self view];
 col = ctr % 2 ? [UIColor blueColor].CGColor : [UIColor redColor].CGColor;

 [self aniFromColor:v.theSquare.backgroundColor toColor:col];

 ctr++;
}

- (void)aniFromColor:(CGColorRef)fromCol toColor:(CGColorRef)toCol {
 FlipLayer3View *v = (FlipLayer3View *)[self view];
 const CGFloat *fromColors = CGColorGetComponents(fromCol);
 const CGFloat *toColors = CGColorGetComponents(toCol);

 v.theSquare.backgroundColor = fromCol;

 ani1 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
 [ani1 setDuration:dur];
 [ani1 setToValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
 [ani1 setValue:@"shrink" forKey:@"name"];
 [ani1 setDelegate:self];
 [ani1 setFillMode:kCAFillModeForwards];
 [ani1 setRemovedOnCompletion:NO];

 ani2 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
 UIColor *c1 = [UIColor colorWithRed:(fromColors[0]/2.0f) green:(fromColors[1]/2.0f) blue:(fromColors[2]/2.0f) alpha:1.0f];

 const float *cgCol1 = CGColorGetComponents(fromCol);
 const float *cgCol2 = CGColorGetComponents(c1.CGColor);
 NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
 NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);

 [ani2 setDuration:dur];
 [ani2 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
 [ani2 setFromValue:(id)fromCol];
 [ani2 setToValue:(id)c1.CGColor];
 [ani2 setValue:@"dim" forKey:@"name"];
 [ani2 setDelegate:self];
 [ani2 setFillMode:kCAFillModeForwards];
 [ani2 setRemovedOnCompletion:NO];

 ani3 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
 [ani3 setDuration:dur];
 [ani3 setFromValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
 [ani3 setToValue:[NSValue valueWithCATransform3D:v.theSquare.transform]];
 [ani3 setValue:@"grow" forKey:@"name"];
 [ani3 setTimeOffset:dur];
 [ani3 setDelegate:self];
 [ani3 setFillMode:kCAFillModeForwards];
 [ani3 setRemovedOnCompletion:NO];

 ani4 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
 UIColor *c2 = [UIColor colorWithRed:(toColors[0]/2.0f) green:(toColors[1]/2.0f) blue:(toColors[2]/2.0f) alpha:1.0f];

 cgCol1 = CGColorGetComponents(c2.CGColor);
 cgCol2 = CGColorGetComponents(toCol);
 NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
 NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);

 [ani4 setDuration:dur];
 [ani4 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
 [ani4 setFromValue:(id)c2.CGColor];
 [ani4 setToValue:(id)toCol];
 [ani4 setValue:@"glow" forKey:@"name"];
 [ani4 setTimeOffset:dur];
 [ani4 setDelegate:self];
 [ani4 setFillMode:kCAFillModeForwards];
 [ani4 setRemovedOnCompletion:NO];

 [v.theSquare addAnimation:ani1 forKey:@"rotate1"];
 [v.theSquare addAnimation:ani2 forKey:@"fadeout"];
 [v.theSquare addAnimation:ani3 forKey:@"rotate2"];
 [v.theSquare addAnimation:ani4 forKey:@"fadein"];
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
 if (flag) {
  NSString *str = [anim valueForKey:@"name"];

  if ([str isEqual:@"shrink"]) {
   NSLog(@"SHRINK complete...");
  }
  else if ([str isEqual:@"dim"]) {
   NSLog(@"DIM complete...");

   FlipLayer3View *theView = (FlipLayer3View *)[self view];
   theView.theSquare.backgroundColor = col;
  }
  else if ([str isEqual:@"grow"]) {
   NSLog(@"GROW complete...");
  }
  else if ([str isEqual:@"glow"]) {
   NSLog(@"GLOW complete...");
  }
 }
}

, и здесь FWIW - это код, который я использовал с решением CAAnimationGroup:

<pre><code>
- (IBAction)handleButtonClick {
 FlipLayer3View *v = (FlipLayer3View *)[self view];
 CGColorRef c = ctr % 2 ? [UIColor redColor].CGColor : [UIColor blueColor].CGColor;

 aniGroup = [self aniFromColor:v.theSquare.backgroundColor toColor:c];

 [v.theSquare addAnimation:aniGroup forKey:@"rotate"];
 ctr++;
}

- (CAAnimationGroup *)aniFromColor:(CGColorRef)fromCol toColor:(CGColorRef)toCol {
 FlipLayer3View *v = (FlipLayer3View *)[self view];
 const CGFloat *fromColors = CGColorGetComponents(fromCol);
 const CGFloat *toColors = CGColorGetComponents(toCol);

 ani1 = [CABasicAnimation animationWithKeyPath:@"transform"];
 [ani1 setDuration:dur];
 [ani1 setToValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
 [ani1 setValue:@"shrink" forKey:@"name"];

 ani2 = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
 UIColor *c1 = [UIColor colorWithRed:(fromColors[0]/2.0f) green:(fromColors[1]/2.0f) blue:(fromColors[2]/2.0f) alpha:1.0f];
 [ani2 setDuration:dur];
 [ani2 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
 [ani2 setToValue:(id)c1.CGColor];
 [ani2 setValue:@"dim" forKey:@"name"];

 ani3 = [CABasicAnimation animationWithKeyPath:@"transform"];
 [ani3 setDuration:dur];
 [ani3 setFromValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
 [ani3 setToValue:[NSValue valueWithCATransform3D:v.theSquare.transform]];
 [ani3 setValue:@"grow" forKey:@"name"];
 [ani3 setBeginTime:dur];

 ani4 = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
 UIColor *c2 = [UIColor colorWithRed:(toColors[0]/2.0f) green:(toColors[1]/2.0f) blue:(toColors[2]/2.0f) alpha:1.0f];
 [ani4 setDuration:dur];
 [ani4 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
 [ani4 setFromValue:(id)c2.CGColor];
 [ani4 setToValue:(id)toCol];
 [ani4 setValue:@"glow" forKey:@"name"];
 [ani4 setBeginTime:dur];

 aniGroup = [CAAnimationGroup animation];
 [aniGroup setDuration:dur*2];
 [aniGroup setAnimations:[NSArray arrayWithObjects:ani1, ani2, ani3, ani4, nil]];
 [aniGroup setFillMode:kCAFillModeForwards];
 [aniGroup setRemovedOnCompletion:NO];

 return aniGroup;
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
 if (flag) {
  NSString *str = [anim valueForKey:@"name"];

  if ([str isEqual:@"shrink"]) {
   NSLog(@"SHRINK complete...");
  }
  else if ([str isEqual:@"dim"]) {
   NSLog(@"DIM complete...");
  }
  else if ([str isEqual:@"grow"]) {
   NSLog(@"GROW complete...");
  }
  else if ([str isEqual:@"glow"]) {
   NSLog(@"GLOW complete...");
  }
 }
}

Кто-то, ПОЖАЛУЙСТА, скажите мне, что я скучаю по тому, что мне не хватает ... это убивает меня!

Спасибо!

Крис

1 Ответ

2 голосов
/ 30 июня 2010

Хорошо, так что позвольте мне быть первым, кто назовет меня идиотом ... В версии группы, которую я попробовал первым, у меня был набор beginTime, но он не должен был быть удален при преобразовании в отдельные анимации, в результате вторая половина анимационной последовательности потерпела неудачу. Это заставило меня попытаться установить timeOffset, что дало странный результат не запуска первой половины, а второй.

Я просто вошел и удалил все это, beginTime, timeOffset и т. Д. Затем запустил первые две анимации. Затем в методе animationDidStop: finish: я меняю цвет слоя, являющегося анимацией, чтобы избежать возврата флэш-памяти к исходному цвету, и, наконец, запускаю второй набор анимаций. Et Viola !!!

Для справки вот рабочий код:


- (IBAction)handleButtonClick {
    FlipLayer3View *v = (FlipLayer3View *)[self view];
    col = ctr % 2 ? [UIColor blueColor].CGColor : [UIColor redColor].CGColor;

    [self aniFromColor:v.theSquare.backgroundColor toColor:col];

    ctr++;
}

- (void)aniFromColor:(CGColorRef)fromCol toColor:(CGColorRef)toCol {
    FlipLayer3View *v = (FlipLayer3View *)[self view];
    const CGFloat *fromColors = CGColorGetComponents(fromCol);
    const CGFloat *toColors = CGColorGetComponents(toCol);

    v.theSquare.backgroundColor = fromCol;

    ani1 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
    [ani1 setDuration:dur];
    [ani1 setToValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
    [ani1 setValue:@"shrink" forKey:@"name"];
    [ani1 setDelegate:self];
    [ani1 setFillMode:kCAFillModeForwards];
    [ani1 setRemovedOnCompletion:NO];

    ani2 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
    UIColor *c1 = [UIColor colorWithRed:(fromColors[0]/2.0f) green:(fromColors[1]/2.0f) blue:(fromColors[2]/2.0f) alpha:1.0f];

    const float *cgCol1 = CGColorGetComponents(fromCol);
    const float *cgCol2 = CGColorGetComponents(c1.CGColor);
    NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
    NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);

    [ani2 setDuration:dur];
    [ani2 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
    [ani2 setFromValue:(id)fromCol];
    [ani2 setToValue:(id)c1.CGColor];
    [ani2 setValue:@"dim" forKey:@"name"];
    [ani2 setDelegate:self];
    [ani2 setFillMode:kCAFillModeForwards];
    [ani2 setRemovedOnCompletion:NO];

    ani3 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
    [ani3 setDuration:dur];
    [ani3 setFromValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
    [ani3 setToValue:[NSValue valueWithCATransform3D:v.theSquare.transform]];
    [ani3 setValue:@"grow" forKey:@"name"]; [ani3 setDelegate:self];
    [ani3 setFillMode:kCAFillModeForwards];
    [ani3 setRemovedOnCompletion:NO];

    ani4 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
    UIColor *c2 = [UIColor colorWithRed:(toColors[0]/2.0f) green:(toColors[1]/2.0f) blue:(toColors[2]/2.0f) alpha:1.0f];

    cgCol1 = CGColorGetComponents(c2.CGColor);
    cgCol2 = CGColorGetComponents(toCol);
    NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
    NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);

    [ani4 setDuration:dur];
    [ani4 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    [ani4 setFromValue:(id)c2.CGColor];
    [ani4 setToValue:(id)toCol];
    [ani4 setValue:@"glow" forKey:@"name"]; [ani4 setDelegate:self];
    [ani4 setFillMode:kCAFillModeForwards];
    [ani4 setRemovedOnCompletion:NO];

    [v.theSquare addAnimation:ani1 forKey:@"rotate1"];
    [v.theSquare addAnimation:ani2 forKey:@"fadeout"];

}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (flag) {
        NSString *str = [anim valueForKey:@"name"];

        if ([str isEqual:@"shrink"]) {
            NSLog(@"SHRINK complete...");
        }
        else if ([str isEqual:@"dim"]) {
            NSLog(@"DIM complete...");

            FlipLayer3View *theView = (FlipLayer3View *)[self view];
            theView.theSquare.backgroundColor = col;
            [theView.theSquare addAnimation:ani3 forKey:@"rotate2"];
            [theView.theSquare addAnimation:ani4 forKey:@"fadein"];
        }
        else if ([str isEqual:@"grow"]) {
            NSLog(@"GROW complete...");
        }
        else if ([str isEqual:@"glow"]) {
            NSLog(@"GLOW complete...");
        }
    }
}

Если кто-то видит проблемы или знает лучший способ, я хотел бы услышать !!

Спасибо

Chris

...