Могу ли я использовать CGAffineTransformMakeRotation для поворота изображения более чем на 360 градусов?

Я пишу приложение для iPhone, и у меня есть изображение, которое я хотел бы выкрутить наружу.

В настоящее время мой код выглядит так (завершен в блок beginAnimations/commitAnimations):

scale = CGAffineTransformScale(CGAffineTransformIdentity, 5.0f, 5.0f);
swirl = CGAffineTransformRotate(scale, M_PI);
[player setTransform:swirl];    
[player setAlpha:0.0f];

Но я нахожу, что если я попытаюсь изменить угол поворота на, скажем, 4 * M_PI, он вообще не вращается. Можно ли получить поворот 720˚ с помощью CGAffineTransformRotate, или мне нужно переключиться на другую технологию?

Если мне нужно переключиться на другую технологию, вы бы порекомендовали использовать другой поток (или таймер) для самой анимации или OpenGL был бы лучшим маршрутом?

Спасибо,
Блейк.

Ответ 1

Вы можете поворачивать представление некоторым количеством радианов, независимо от того, меньше ли это полного вращения или много кратных полного вращения, без необходимости разделить поворот на куски. Например, следующий код будет вращать просмотр один раз в секунду в течение заданного количества секунд. Вы можете легко изменить его, чтобы вращать вид на определенное количество вращений или на некоторое количество радианов.

- (void) runSpinAnimationWithDuration:(CGFloat) duration;
{
    CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
    rotationAnimation.duration = duration;
    rotationAnimation.cumulative = YES;
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    [myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}

Ответ 2

Вы можете, но вам нужно разделить свою анимацию на полукруговые вращения. Я приведу пример этого в ответ на этот вопрос, используя повторяющуюся CABasicAnimation, применяемую к слою под представлением. Как я предлагаю там, делать эти половинные вращения как части CAKeyframeAnimation, вероятно, будет лучшим способом структурировать это, потому что анимация будет более гладкой (там небольшое сцепление между полувращениями в моем примере), и вы могли бы сделать хорошее ускорение/замедление в начале и конце.

Ответ 3

Ответ на заголовок: Да, CGAffineTransform может вращаться более чем на 360 градусов. Ответьте на вопрос: Да, но вы не можете его оживить, потому что ничего не нужно оживлять.

Помните, что аффинное преобразование - это матрица, и что матрица вращения содержит синусоидальные и косинусные числа, предварительно вычисленные. Как будто вы сказали:

CGFloat angle = 4.0 * M_PI;
NSAffineTransformStruct matrix = {
    .m11 = cos(angle),
    .m12 = sin(angle),
    .m21 = -sin(angle),
    .m22 = cos(angle),
    .tx = 0.0,
    .ty = 0.0
};
NSAffineTransform *transform = [NSAffineTransform transform];
[transform setTransformStruct:matrix];

Теперь рассмотрим некоторые примерные значения для cos и sin:

  • cos(0π)= 1
  • sin(0π)= 0
  • cos(2π)= 1
  • sin(2π)= 0
  • cos(4π)= 1
  • sin(4π)= 0

Помните, что матрица не содержит угла - она ​​содержит только косинус и синус. И эти значения не меняются от одного кратного круга к другому. Поэтому нет ничего, что можно было бы оживить.

(Обратите внимание, что Calculator.app дает неверные результаты для cos (xπ) и sin (xπ). Попробуйте Grapher, calc, или Google.)

Вам нужно разбить анимацию на доли круга. Полукруги, предложенные Брэдом Ларсоном, будут очень хорошими.