Могу ли я использовать CGAffineTransformMakeRotation для поворота вида более чем на 360 градусов? - PullRequest
28 голосов
/ 12 февраля 2009

Я пишу приложение для 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 был бы лучшим путем?

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

Ответы [ 3 ]

64 голосов
/ 14 сентября 2009

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

- (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"];
}
5 голосов
/ 13 февраля 2009

Ответ на заголовок: Да, 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 .)

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

5 голосов
/ 12 февраля 2009

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

...