Help us understand the problem. What is going on with this article?

removedOnCompletionをfalseにするならanimationDidStopでremoveAnimationを実行した方が良い(かも)

More than 3 years have passed since last update.

16/11/12 修正

iOS10から既存のanimationDidStopは廃止になりました。

QuartzCore Changes for Swift

今まではNSObjectのメソッドでしたが、今後はCAAnimationのメソッドになります。
よってanimationDidStopの呼び出しも変更になります。

class ViewController: UIViewController, CAAnimationDelegate{ //<- CAAnimationのDelegateが追加が必要

今まではDelegateの指定が要らなかったのですが、今度から必要です。

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {

}

overrideの指定も不要です。
以上、変更点でした。

16/03/14 タイトル及び本文修正

CABasicAnimationで変更した結果のままにしたい場合は以下のようにします。

let animateStrokeEnd = CABasicAnimation(keyPath: "progress")
animateStrokeEnd.delegate = self // animationDidStopを呼び出すのに必須
animateStrokeEnd.fromValue = fromValue
animateStrokeEnd.toValue = toValue 
animateStrokeEnd.removedOnCompletion = false
animateStrokeEnd.fillMode = kCAFillModeForwards
_sublayer?.addAnimation(animateStrokeEnd, forKey: "progress")

しかし、この状態はアニメーションの処理がずっと動きっぱなしの状態でしかも実際にはCALayerの値を変更してるわけではないようです。
なので、アニメーションを止める且つCALayerの値を実際に変更してやる必要があるけど、animationDidStopで実行してやると丁度良いのではないかと。

    override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
        _sublayer?.propery = toValue
        _sublayer?.removeAnimationForKey("progress")  //こちらか下か
        _sublayer?.removeAllAnimations() // どちらか都合の良い方を使う
    }

以上です。書きたかった事をまとめればえらくシンプルになりました。

下記は修正前15/10/10時点の記事。備忘録でとりあえず残しておきます。


ちょっとまだ整理仕切れてないけど。
CABasicAnimationとUIBezierPathを使ったアニメーションを試していたところ、CABasicAnimationのアニメーションとはCALayerのdrawInContextをプロパティのfromValueからtoValueまで再描画を繰り返す動きをしている事だと分かった。
(CALayerのサブクラスでdrawInContextでログを出すようにでもして貰ったら分かります。)
ところで、CABasicAnimationはアニメーションが終了したら、描画した内容がクリアされる問題があって、それを解決するにはプロパティのremovedOnCompletionとfillModeをセットで設定してやる。こんな形で。

let animateStrokeEnd = CABasicAnimation(keyPath: "progress")
animateStrokeEnd.fromValue = fromValue
animateStrokeEnd.toValue = toValue            
animateStrokeEnd.removedOnCompletion = false
animateStrokeEnd.fillMode = kCAFillModeForwards

ところがプロパティのremovedOnCompletionを使うとtoValueまでの値になっても再描画の動きが止まらない事が判明。removedOnCompletionという単語の意味を考えればそうなってもおかしくないのだが、最近まで全然気付いてなかった・・・。
なんにせよ、removedOnCompletionを使うとずっとアニメーションそのものを削るかそのアニメーションをしているCALayerそのものを削除しない限り、処理が動きっぱなしだと言う事。それはあまり良くないので、アニメーションを削るか、CALayerを削除する処理をしないならremovedOnCompletionは使わない方がよい。
その代わりの処理としては以下のような方法がいいみたいです。

/* 別のファイルもしくは上記でサブレイヤークラスを作成 */

var _subLayer : SubLayer? = nil

/* 省略 */

func moveLayer {
let animateStrokeEnd = CABasicAnimation(keyPath: "progress")
animateStrokeEnd.fromValue = fromValue
animateStrokeEnd.toValue = toValue            
//animateStrokeEnd.removedOnCompletion = false コメントアウト
animateStrokeEnd.fillMode = kCAFillModeForwards
animateStrokeEnd.delegate = self //デリゲートを設定
_sublayer?.addAnimation(animateStrokeEnd, forKey: "progress")

}

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
let pinnedProgressNumber : CGFloat = anim.valueForKey("toValue") as CGFloat
_sublayer?.toValue = pinnedProgressNumber        

}

CABasicAnimationのデリゲートをセットし、アニメーションの終了時に呼び出されるメソッドをオーバーライド。その中で、アニメーション後の値をセットしてやる。例えば移動のアニメーションなら移動先の座標など。

以上です。


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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした