2012-05-08 8 views
10

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

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState animations:^{ 
    self.reloadButton.imageView.transform = CGAffineTransformRotate(self.reloadButton.imageView.transform, -M_PI); 
} completion:^(BOOL finished) { 

}]; 

Согласно документации, то знаковость угла я перейти к CGAffineTransformRotate определяет направление вращения, но выше код вращается против часовой стрелки. То же самое с M_PI.

Угол в радианах, с помощью которого эта матрица вращает координату осями системы. В iOS положительное значение указывает против часовой стрелки вращение, а отрицательное значение указывает вращение по часовой стрелке. В Mac OS X положительное значение указывает вращение по часовой стрелке и отрицательное значение указывает вращение против часовой стрелки.

+0

Что произойдет, если вы делаете поворот на imageViews слой с CATransform3D? –

+0

Вы пробовали вращаться под другими углами (скажем, на 180 градусов)? – giorashc

+0

@David Спасибо за предложение, но это привело к таким же результатам: self.reloadButton.imageView.layer.transform = CATransform3DMakeRotation (-M_PI, 0, 0, 1); – Morrowless

ответ

14

Кристоф уже идет правильным путем, но есть гораздо лучший способ держать его вращением, не переучивая его в делегатах анимации каждый раз, когда он заканчивается. Это просто неправильно.

Просто установите свойство repeatCount вашей анимации на HUGE_VALF.

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
animation.fromValue = @0.0f; 
animation.toValue = @(2*M_PI); 
animation.duration = 0.5f;    // this might be too fast 
animation.repeatCount = HUGE_VALF;  // HUGE_VALF is defined in math.h so import it 
[self.reloadButton.imageView.layer addAnimation:animation forKey:@"rotation"]; 

Как указано in the documentation, это приведет к анимации повторить навсегда.

+1

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

+1

Спасибо за код! works GREAT – eric

+0

Просто используйте 'CGFLOAT_MAX' вместо импорта чего-либо. –

1

К сожалению пропустил первую часть, вид вращается нормально, используя меньший угол:

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState animations:^{ 
     redView.transform = CGAffineTransformRotate(redView.transform, M_PI_2); 
    } completion:^(BOOL finished) { 

    }]; 

Я не смог найти каких-либо существенных объяснений, почему он терпит неудачу с M_PI.

+0

Повторение - это именно то, что я хочу, проблема в том, что он не вращается по часовой стрелке. – Morrowless

+0

Я думаю, что это потому, что конечное состояние вращения совпадает с исходным состоянием. – giorashc

1

Я столкнулся с той же проблемой некоторое время назад. Я не помню причину этого вопроса, но это мое решение:

/** 
* Incrementally rotated the arrow view by a given angle. 
* 
* @param degrees Angle in degrees. 
* @param duration Duration of the rotation animation. 
*/ 
- (void)rotateArrowViewByAngle:(CGFloat)degrees 
        withDuration:(NSTimeInterval)duration { 

    CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    spinAnimation.fromValue = [NSNumber numberWithFloat:self.currentAngle/180.0 * M_PI]; 
    spinAnimation.toValue = [NSNumber numberWithFloat:degrees/180.0 * M_PI]; 
    spinAnimation.duration = duration; 
    spinAnimation.cumulative = YES; 
    spinAnimation.additive = YES; 
    spinAnimation.removedOnCompletion = NO; 
    spinAnimation.delegate = self; 
    spinAnimation.fillMode = kCAFillModeForwards; 

    [self.arrowView.layer addAnimation:spinAnimation forKey:@"spinAnimation"]; 

    self.currentAngle = degrees; 
} 

, а затем вы можете использовать методы делегата

- (void)animationDidStart:(CAAnimation *)theAnimation 
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag 

вращаться держать его вращение. Кроме того, параметры степени и продолжительности могут быть действительно большими числами ... если этого достаточно.

UPDATE:
Как заявил yinkou,

spinAnimation.repeatCount = HUGE_VALF;  // HUGE_VALF is defined in math.h so import it 

является способ лучше, что возобновление анимации в делегатом.

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ:
self.currentAngle - это свойство, помнящее текущее окончательное вращение.
Мне нужно было, чтобы вид поворачивался влево и вправо.

Смежные вопросы