2012-06-19 4 views
5

Я использую анимацию вращения, созданную с помощью CABasicAnimation. Он вращает UIView в течение 2 секунд. Но мне нужно остановить его, когда коснется UIView. Если я удалю анимацию, представление будет в том же положении, что и до начала анимации.Остановить CABasicAnimation в определенной точке

Вот мой код анимации:

float duration = 2.0; 
float rotationAngle = rotationDirection * ang * speed * duration; 
//rotationAngle = 3*(2*M_PI);//(double)rotationAngle % (double)(2*M_PI) ; 
CABasicAnimation* rotationAnimation; 
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
rotationAnimation.toValue = [NSNumber numberWithFloat: rotationAngle ]; 
rotationAnimation.duration = duration; 
rotationAnimation.cumulative = YES; 
rotationAnimation.removedOnCompletion = NO; 
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
rotationAnimation.fillMode = kCAFillModeForwards; 
rotationAnimation.delegate = self; 

[self.view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 

Как я могу остановить вращение правильно их UIView «s, где она есть, когда он прикоснулся? Я знаю, как управлять сенсорной частью, но я не могу понять, как остановить просмотр на текущем угле.

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

[self.view.layer removeAllAnimations];  
CALayer* presentLayer = self.view.layer.presentationLayer; 
float currentAngle = [(NSNumber *)[presentLayer valueForKeyPath:@"transform.rotation.z"] floatValue]; 
self.view.transform = CGAffineTransformMakeRotation(currentAngle); 
+1

где вы положили вышеуказанное решение ?? Я всегда получаю угол 0.0000 – Hisenberg

ответ

15

Хороший вопрос! Для этого полезно знать архитектуру Core Animation.

Если вы посмотрите диаграмму в Core Animation Programming Guide, которая описывает архитектуру рендеринга Core Animation, вы увидите, что есть три дерева.

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

В вашем случае вы хотите запросить значения представления дерева.

Это легко сделать. Для представления, которое вы приложили к анимации, получите layer и за это layer запросите значения presentationLayer. Например:

CATransform3D myTransform = [(CALayer*)[self.view.layer presentationLayer] transform]; 

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

Это немного боль!

Посмотрите на некоторые из моих других сообщений, где я вхожу в это более подробно, например.

Restoring animation where it left off when app resumes from background

Не забывайте также, что при добавлении анимации слоя в целях, вы не на самом деле изменений свойств подстилающего вида. Так что же происходит?Мы получим странные эффекты, когда анимация остановится, и вы увидите вид в исходной позиции.

Здесь вы должны использовать делегатов CAAnimation. Посмотрите на мой ответ на этот пост, где я покрываю это:

CABasicAnimation rotate returns to original position

+1

Благодарим вас за объяснение уровня презентации. Я решил проблему, получив угол поворота презентационного слоя со значениемForKeyPath :, установив преобразование вида и удалив анимацию. –

5

Вы должны установить вращение вращения presentationLayer, а затем удалить анимацию из слоя. Вы можете прочитать о слое презентации в своем сообщении в блоге о Hit testing animating layers.

Код для установки окончательного поворота будет что-то вроде:

self.view.layer.transform = [(CALayer*)[self.view.layer presentationLayer] transform]; 
[self.view.layer removeAnimationForKey:@"rotationAnimation"]; 
Смежные вопросы