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


## 16/11/12 修正

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

[QuartzCore Changes for Swift](https://developer.apple.com/library/content/releasenotes/General/iOS10APIDiffs/Swift/QuartzCore.html)

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

以上です。

---------------------------------------