Ответ 1
У вас есть три варианта.
При использовании методов -[UIView animateWithDuration:…]
изменения, внесенные вами в блок animations
, немедленно применяются к рассматриваемым представлениям. Однако также существует неявный CAAnimation
, примененный к представлению, которое анимируется от старого значения до нового значения. Когда a CAAnimation
активен в представлении, он изменяет отображаемое представление, но не изменяет фактические свойства представления.
Например, если вы это сделаете:
NSLog(@"old center: %@", NSStringFromCGPoint(someView.center));
[UIView animateWithDuration:2.0 animations: ^{ someView.center = newPoint; }];
NSLog(@"new center: %@", NSStringFromCGPoint(someView.center));
вы увидите, что "старый центр" и "новый центр" различны; новый центр сразу отразит значения newPoint. Однако CAAnimation
, который был неявно создан, заставит представление все еще отображаться в старом центре и плавно переходить к новому центру. Когда анимация закончится, она будет удалена из представления и вы вернетесь к простому отображению фактических значений модели.
Когда вы передаете UIViewAnimationOptionAutoreverse
, это влияет на неявно созданный CAAnimation
, но НЕ влияет на фактическое изменение, которое вы делаете на значения. То есть, если наш пример выше имел значение UIViewAnimationOptionAutoreverse
, то неявно созданный CAAnimation
мог бы анимироваться от oldCenter до newCenter и обратно. Затем анимация будет удалена, и мы вернемся к просмотру значений, которые мы установили... , которые все еще находятся в новой позиции.
Как я уже сказал, есть три способа справиться с этим. Первый заключается в том, чтобы добавить блок завершения анимации, чтобы отменить его, например:
Первый вариант
CGPoint oldCenter = someView.center;
[UIView animateWithDuration:2.0
animations: ^{ someView.center = newPoint; }
completion:
^(BOOL finished) {
[UIView animateWithDuration:2.0
animations:^{ someView.center = oldCenter; }];
}];
Второй вариант
Второй вариант состоит в том, чтобы автореверсировать анимацию, как вы делаете, и вернуть представление в исходное положение в блок завершения:
CGPoint oldCenter = someView.center;
[UIView animateWithDuration:2.0
delay:0
options: UIViewAnimationOptionAutoreverse
animations: ^{ someView.center = newPoint; }
completion: ^(BOOL finished) { someView.center = oldCenter; }];
Однако это может вызвать мерцание между временем завершения автореверса анимации и завершением блока завершения, поэтому, вероятно, это не ваш лучший выбор.
Третий вариант
Последний вариант - просто создать CAAnimation
напрямую. Когда вы фактически не хотите изменять конечное значение свойства, которое вы меняете, это часто бывает проще.
#import <QuartzCore/QuartzCore.h>
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.autoreverses = YES;
animation.repeatCount = 1; // Play it just once, and then reverse it
animation.toValue = [NSValue valueWithCGPoint:newPoint];
[someView.layer addAnimation:animation forKey:nil];
Обратите внимание, что способ CAAnimation
делать вещи никогда не изменяет фактические значения представления; он просто маскирует фактические значения с помощью анимации. Представление все еще думает об этом в исходном месте. (Это означает, например, что если ваше мнение реагирует на события касания, оно все равно будет следить за тем, чтобы те события касания происходили в исходном местоположении. Анимация меняет способ отображения только ничему.
Способ CAAnimation
также требует, чтобы вы добавили его в представление, лежащее в основе CALayer
. Если это вас пугает, не стесняйтесь использовать методы -[UIView animateWithDuration:…]
. Доступны дополнительные функции с помощью CAAnimation
, но если это то, что вы не знакомы, целая анимация UIView или ее сброс в блоке завершения вполне приемлемы. На самом деле, это одна из основных целей блока завершения.
Итак, вы идете. Три разных способа изменить анимацию и сохранить исходное значение. Наслаждайтесь!