Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[iOS]UIView.animateがキャンセルされ、completionが呼ばれる問題

More than 1 year has passed since last update.

長年疑問だった挙動を確認しました。

hogeViewX.constant = 100
UIView.animate(withDuration: TimeInterval(2.0),
               animations: {
                self.view.layoutIfNeeded() },
               completion: { (finished) in
                print("🤔")
})

例えばこういうアニメーションを、アニメーション中に複数回呼ぶと、前のがキャンセルされてcompletionが呼ばれます。
completionのfinishedはなぜかtrueを返すので、キャンセルされたかどうかがわかりません。

困ること

例えばanimationの発火ボタンを連打しても、問題ないように見えます。
しかし、completionで例えばisHidden = trueとしていたりすると厄介です。
アニメーション後に消えてほしいのに、2回目を押した瞬間に消えてしまいます。

回避方法1.フラグで管理

1回目のアニメーションが終わるまで他の同一のアニメーションを排除します
これは上手く動きました

回避方法2.別のアニメーションと判断させる

内部的に、animationの中身(アニメーション対象?)が同じなら同じアニメーションと判断しているようです。
なのでこういう風にanimationの中身を変えてしまえばゴリ押しで解決できるようです。

hogeViewX.constant = CGFloat(100 + Float.random(in: 0..<1.0))
UIView.animate(withDuration: TimeInterval(2.0),
               animations: {
                self.view.layoutIfNeeded() },
               completion: { (finished) in
                print("🤔")
})

回避方法3.他のアニメーションを使う

これはStackOverflowであったものの未確認

この問題に、どこで遭遇しやすいか

scrollViewDidScrollでアニメーションを呼ぶ時に起こりがちです

公式仕様は?

発見できませんでした
あまり話題になってるのも見たことがありません
でも私は定期的にこの問題に遭遇します

netetahito
モバイルアプリエンジニア(9年目) 現在はフリーランスで複業を行っています。 サービス系アプリをビジネスモデルから考えるのが好きで社会インフラになるようなアプリを一から作るのが目標。
http://otihateten.hatenablog.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away