Как отменить предыдущую анимацию при срабатывании нового?
Я пишу приложение для камеры и испытываю проблемы с отображением квадрата фокуса, когда пользователь нажимает на экран.
Мой код (быстро):
self.focusView.center = sender.locationInView(self.cameraWrapper)
self.focusView.transform = CGAffineTransformMakeScale(2, 2)
self.focusView.hidden = false
UIView.animateWithDuration(0.5, animations: { [unowned self] () -> Void in
self.focusView.transform = CGAffineTransformIdentity
}, completion: { (finished) -> Void in
UIView.animateWithDuration(0.5, delay: 1.0, options: nil, animations: { () -> Void in
self.focusView.alpha = 0.0
}, completion: { (finished) -> Void in
self.focusView.hidden = true
self.focusView.alpha = 1.0
})
})
Однако, если использование последовательно нажимает экран, когда предыдущая анимация не заканчивается, старая и новая анимация будет смешиваться, и фокус будет вести себя странно, например, он исчезнет очень быстро.
Может ли кто-нибудь сказать мне, как отменить предыдущую анимацию, особенно предыдущий блок завершения?
Ответы
Ответ 1
Пользовательский метод removeAllAnimations
для остановки анимации
Замените код ниже.
self.focusView.center = sender.locationInView(self.cameraWrapper)
self.focusView.transform = CGAffineTransformMakeScale(2, 2)
self.focusView.hidden = false
self.focusView.layer.removeAllAnimations() // <<==== Solution
UIView.animateWithDuration(0.5, animations: { [unowned self] () -> Void in
self.focusView.transform = CGAffineTransformIdentity
}, completion: { (finished) -> Void in
UIView.animateWithDuration(0.5, delay: 1.0, options: nil, animations: { () -> Void in
self.focusView.alpha = 0.0
}, completion: { (finished) -> Void in
self.focusView.hidden = true
self.focusView.alpha = 1.0
})
})
Ссылка: ссылка
![enter image description here]()
Ответ 2
В моем случае я добавляю индикатор фокусировки с помощью addSubview()
.
self.view.addSubview(square)
square - это UIView I, определенный в функции. Поэтому, когда пользователь нажимает экран для фокусировки, эта функция добавит квадрат в subview.
И чтобы отменить эту анимацию, когда произойдет следующий щелчок, я просто просто использую функцию removeFromSuperview(), когда эта функция называется им, удаляет вид из своего супервизора, который здесь является фокусом.
filterView.subviews.forEach({ $0.removeFromSuperview() })
Он отличается от метода выше, чтобы удалить анимацию, но удалите subview напрямую.
Ответ 3
В моем случае мне просто нужно было установить значение i, анимированное для конкретного значения.
Например,
if ([indexPath isEqual:self.currentPlayerOrderIndexPath])
{
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut
animations:^{
cell.avatarImageV.transform = CGAffineTransformMakeScale(1.15,1.15);
}
completion:NULL];
}
else
{
cell.avatarImageV.transform = CGAffineTransformMakeScale(1.0, 1.0);
Ответ 4
Решение @Jageen великолепно, но я работал с анимацией UIStackView и там мне потребовались дополнительные шаги. У меня есть stackView с view1 и view2 внутри, и один вид должен быть видимым, а другой скрытым:
public func configureStackView(hideView1: Bool, hideView2: Bool) {
let oldHideView1 = view1.isHidden
let oldHideView2 = view2.isHidden
view1.layer.removeAllAnimations()
view2.layer.removeAllAnimations()
view.layer.removeAllAnimations()
stackView.layer.removeAllAnimations()
// after stopping animation the values are unpredictable, so set values to old
view1.isHidden = oldHideView1 // <- Solution is here
view2.isHidden = oldHideView2 // <- Solution is here
UIView.animate(withDuration: 0.3,
delay: 0.0,
usingSpringWithDamping: 0.9,
initialSpringVelocity: 1,
options: [],
animations: {
view1.isHidden = hideView1
view2.isHidden = hideView2
stackView.layoutIfNeeded()
},
completion: nil)
}