Принудительное вращение по часовой стрелке/против часовой стрелки для CABasicAnimation UIImageView

Я анимирую маятник, который качается от 0 градусов до максимум 200 градусов, а затем обратно. Проблема в том, что если маятник проходит более 180 градусов, он возвращается к 0 по кратчайшему пути, который должен продолжаться по часовой стрелке. И я бы хотел, чтобы он шел против часовой стрелки. Вот мой код: («право» — это логическое значение, которое является ИСТИННЫМ, когда маятник качается слева направо)

 - (void)swingPendulum {
    CABasicAnimation *rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    if (right) 
        rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMax)];
    else
        rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMin)];                               
    rotationAnimation.duration = 1.0;
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.delegate = self;
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    rotationAnimation.removedOnCompletion = NO;

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

Любые идеи, как я могу сделать эту работу? Это последняя часть моей головоломки свингометра, которая в остальном отлично работает :D Спасибо!

Майкл


person Smikey    schedule 12.08.2010    source источник


Ответы (4)


Чтобы заставить его двигаться против часовой стрелки, просто установите x на отрицательное значение (добавить - впереди), где вы хотите

rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(x)];
person Lilz    schedule 20.09.2010
comment
Спасибо за ответ, но боюсь, это не имеет значения. Установка для него значения -ive, кажется, просто делает анимацию в конце... Я думаю, возможно, мне придется переписать ее, чтобы использовать NSTimer и анимировать кадр за кадром... - person Smikey; 20.09.2010
comment
На самом деле, вы правы - поскольку kMin в настоящее время установлено на -20, это фактически заставляет маятник качаться против часовой стрелки, но только если он не превышает 180 градусов. Если он превышает 180, то независимо от того, какое значение я установил (-180, -90, 90 и т. д.), он всегда продолжается по часовой стрелке, даже если это не самый короткий маршрут... Есть другие идеи? - person Smikey; 20.09.2010
comment
ААААА, если я установлю значение вроде -380, оно сработает. Я не совсем уверен, почему, но я только что добавил условие, которое переключает toValue в зависимости от того, проходит ли начальный поворот на 180 градусов. Спасибо за помощь! - person Smikey; 20.09.2010

Попробуйте установить что-то вроде

rotationAnimation.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ];

Используя функции преобразования значений, анимации могут влиять на свойство преобразования слоя с помощью произвольных преобразований каждого компонента (без нормализации до 360°) и объединяться, как правило, при одновременном применении нескольких анимаций.

Вы используете функцию преобразования значения, которая вращается от 0° до 180° вокруг оси z, создавая функцию CAValueTransform, указав kCAValueFunctionRotateZ, а затем создавая анимацию с fromValue, равным 0, toValue, равным M_PI, и задавая для свойства valueTransform анимации значение экземпляр преобразования значения.

person tc.    schedule 12.08.2010
comment
Спасибо. Я немного не хочу менять подход, который я уже использую, если нет возможности его исправить, поскольку у меня есть много другого кода, основанного на методах, которые я уже использовал. Как отмечалось выше, я на самом деле создаю свингометр в стиле игры в гольф, а не маятник, поэтому в любой момент пользователь может прервать качание на пути вверх (для определения мощности), и он качнется назад, так что пользователь может прерывание еще раз (для определения точности). У меня есть весь этот функционал, за исключением того, что если пользователь позволяет бару качаться более чем на 180 градусов, он не качается назад, а идет вперед. - person Smikey; 13.08.2010
comment
Попробуй поставить и посмотреть, работает ли? У меня сложилось впечатление, что так и должно быть. - person tc.; 13.08.2010
comment
Я сделал - он начал вести себя довольно странно... Поиграю еще немного и вернусь! - person Smikey; 16.08.2010

Я думаю, вы должны использовать этот код:

[rotationAnimation.byValue = [NSNumber numberWithFloat:degreesToRadians(kMax/2))];
[rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMin)];
person user1985086    schedule 16.01.2013

Я не совсем уверен, в чем проблема, но если вы используете функцию автоматического реверса анимации, вы, вероятно, можете упростить это и заставить ее вращаться (качаться) вперед и назад. Это работает для меня:

CABasicAnimation* rotationAnimation = 
          [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
[rotationAnimation setToValue:[NSNumber numberWithFloat:DegreesToRadians(200.0)]];
[rotationAnimation setDuration:1.0];
[rotationAnimation setRepeatCount:HUGE_VALF]; // Repeat forever
[rotationAnimation setAutoreverses:YES]; // Return to starting point

[[pendulum layer] addAnimation:rotationAnimation forKey:nil];
person Matt Long    schedule 12.08.2010
comment
Хорошая идея, но обратный ход не является точным обращением прямого хода. т.е. качание вперед начинается с 0, а обратное качание возвращается к -20. Поэтому я бы предпочел вызвать функцию, которая отбрасывает его от текущего преобразования к определенному углу. Я не пытаюсь сделать точно маятник, скорее свингометр в стиле игры в гольф - игрок останавливает его один раз на пути вверх для мощности и снова на пути вниз для точности. Это работает отлично, если полоса не превысит 180 градусов по пути вверх, после чего она продолжит движение против часовой стрелки до 0, а не в обратном направлении. Так что мне нужно как-то заставить - person Smikey; 13.08.2010