Дождитесь завершения анимации Swift перед выполнением кода
Я пытаюсь оживить UIImageView, а затем скрыть представление изображения после завершения анимации. Однако изображение будет скрыто до завершения анимации. Я посмотрел на подобные вопросы, и они рекомендуют внедрить прослушиватель анимации или выполнить скрытый код в коде анимации после завершения, но я не уверен, как это повлиять на функцию shakeView() ниже.
Как показать анимацию встряхивания и скрыть представление изображения только после завершения анимации?
Анимация вызывается с использованием следующего кода:
shakeView(image1!)
shakeView(image2)
image1!.hidden = true
image2.hidden = true
Сама функция анимации выглядит так:
func shakeView(iv: UIImageView){
var shake:CABasicAnimation = CABasicAnimation(keyPath: "position")
shake.duration = 0.1
shake.repeatCount = 2
shake.autoreverses = true
var from_point:CGPoint = CGPointMake(iv.center.x - 5, iv.center.y)
var from_value:NSValue = NSValue(CGPoint: from_point)
var to_point:CGPoint = CGPointMake(iv.center.x + 5, iv.center.y)
var to_value:NSValue = NSValue(CGPoint: to_point)
shake.fromValue = from_value
shake.toValue = to_value
iv.layer.addAnimation(shake, forKey: "position")
}
Ответы
Ответ 1
Вы можете использовать CATransaction
для вызова блока завершения после завершения анимации.
func shakeView(iv: UIImageView){
CATransaction.begin()
CATransaction.setCompletionBlock({
iv.hidden = true
})
var shake:CABasicAnimation = CABasicAnimation(keyPath: "position")
shake.duration = 0.1
shake.repeatCount = 21
shake.autoreverses = true
var from_point:CGPoint = CGPointMake(iv.center.x - 5, iv.center.y)
var from_value:NSValue = NSValue(CGPoint: from_point)
var to_point:CGPoint = CGPointMake(iv.center.x + 5, iv.center.y)
var to_value:NSValue = NSValue(CGPoint: to_point)
shake.fromValue = from_value
shake.toValue = to_value
iv.layer.addAnimation(shake, forKey: "position")
CATransaction.commit()
}
Или вы также можете группировать обе анимации вместе в CATransaction
следующим образом.
func shakeView(iv: UIImageView){
var shake:CABasicAnimation = CABasicAnimation(keyPath: "position")
shake.duration = 0.1
shake.repeatCount = 21
shake.autoreverses = true
var from_point:CGPoint = CGPointMake(iv.center.x - 5, iv.center.y)
var from_value:NSValue = NSValue(CGPoint: from_point)
var to_point:CGPoint = CGPointMake(iv.center.x + 5, iv.center.y)
var to_value:NSValue = NSValue(CGPoint: to_point)
shake.fromValue = from_value
shake.toValue = to_value
iv.layer.addAnimation(shake, forKey: "position")
}
override func viewDidLoad() {
CATransaction.begin()
CATransaction.setCompletionBlock({
self.image1.hidden = true
self.image2.hidden = true
})
shakeView(image1)
shakeView(image)
CATransaction.commit()
}
Ответ 2
Как упоминалось в комментарии к Paulw11, вы можете использовать метод animationDidStop:
, упомянутый в документах. Кроме того, вы должны добавить к вам ключ CABasicAnimation/CAAnimation
объектов, чтобы ваш метод animationDidStop:
знал, какой из них был завершен.
Итак, в вашем методе shake добавьте пару value-key для идентификации анимации и установите делегат в self, ex:
func shakeView(iv: UIImageView){
var shake:CABasicAnimation = CABasicAnimation(keyPath: "position")
shake.duration = 0.1
shake.repeatCount = 2
shake.autoreverses = true
// Add these two lines:
shake.setValue("shake", forKey: "animationID")
shake.delegate = self
// ...
Затем добавьте метод делегата animationDidStop:
, чтобы предупредить вас о завершении анимации, чтобы вы могли начать выполнять свой код:
override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
// Unwrap the optional value for the key "animationID" then
// if it equal to the same value as the relevant animation,
// execute the relevant code
if let animationID: AnyObject = anim.valueForKey("animationID") {
if animationID as NSString == "shake" {
// execute code
}
}
}