Повернуть UIImageView по часовой стрелке
Это должно быть просто, но у меня возникают проблемы с поворотом UIImageView
на 360 градусов, повторяющимся навсегда.
[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) {
}];
Согласно документам, подпись угла I, проходящего до CGAffineTransformRotate
, определяет направление вращения, но приведенный выше код вращается против часовой стрелки. То же самое с M_PI
.
Угол в радианах, по которому эта матрица вращает координату системных осей. В iOS положительное значение указывает против часовой стрелки вращение и отрицательное значение указывает вращение по часовой стрелке. В Mac OS X, положительное значение указывает вращение по часовой стрелке и отрицательное значение указывает вращение против часовой стрелки.
Ответы
Ответ 1
Кристоф уже идет правильным путем, но есть гораздо лучший способ, чтобы он вращался, не переустанавливая его в делегатах анимации каждый раз, когда он заканчивается. Это просто неправильно.
Просто установите для свойства 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"];
Как указано в документации, это заставит анимацию повторять навсегда.
Ответ 2
Извините пропущенную первую часть, представление вращается только отлично, используя меньший угол:
[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.
Ответ 3
Я столкнулся с той же проблемой некоторое время назад.
Я не помню причину этой проблемы, но это мое решение:
/**
* 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 - свойство, запоминающее текущее окончательное вращение.
Мне нужно было, чтобы представление поворачивалось влево и вправо.
Ответ 4
Я написал для этого категорию UIImageView: https://gist.github.com/alexhajdu/5658543.
Просто используйте:
[_myImageView rotate360WithDuration:1.0 repeatCount:0]; //0 for infinite loop