

円グラフを作っているのですが、これを下図の左図から右図のようにグラフの値が変わるアニメーションを加えたいです。どのような方法がありますでしょうか。

グレーの部分のコード

[code]

    CGContextSaveGState(context);
    
    CGFloat x = rect.origin.x;
    x += rect.size.width/2;
    
    CGFloat y = rect.origin.y;
    y += rect.size.height/2;
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, x, y, x-10, 0, M_PI*2, NO);
    CGContextAddPath(context, path);
    CGContextSetRGBFillColor(context,0.6, 0.6, 0.6,1.0); //gray
    
    CGContextSetLineWidth(context, 0);
    CGContextSetStrokeColorWithColor(context,[UIColor blackColor].CGColor);
    CGContextDrawPath(context, kCGPathFillStroke);
    
    CGContextRestoreGState(context);
    
[/code]

円グラフは以下のサイトの方法を参考に作成しました。  
<http://qiita.com/rnsm504/items/1c9e71a318fc8bbd5ab8>

![画像の説明をここに入力](https://i.stack.imgur.com/pY7up.png)![画像の説明をここに入力](https://i.stack.imgur.com/ZwRY1.png)


CC BY-SA 3.0
2015-03-13T07:50:35.033
7875
2015-08-10T22:32:06.610
8060
question
objective-c
円グラフにアニメーションをつけたい。


わかりやすい方法として、以下の2つの方法があります。

  1. 一定の間隔でUIViewのsetNeedsDisplay()を呼び出して、drawRect()の中で経過時間に応じたグラフを描画する
  2. あらかじめ複数のUIImageを描画しておいて、UIImageViewの機能を使ってアニメーションさせる

1の方法を使うのであれば、CADisplayLinkについて調べるといいかもしれません。


CC BY-SA 3.0
2015-03-13T16:32:38.137
7893
2015-03-13T16:32:38.137
7459
7875
answer


`CALayer`のサブクラスとして実装し、暗黙のアニメーションに対応させるのが楽だと思います。

### [アニメーションするグラフの実装例](https://gist.github.com/glayash/38aa605f99a9666a925d)

`Swift`練習兼ねてるので、`Swift`で申し訳ありませんがコード例です。雑です。

ただ`Objective-C`でもあまり変わらないと思います。

基本的にやることは以下の4点です。

  1. アニメーションに利用する変数を、キー値コーディング互換（プロパティでOK）にする。
  2. `-drawRect:`の描画処理を、`-drawInContext:`へ移植する。
  3. `+needsDisplayForKey`でキーパス（プロパティ名）が渡されたとき、`YES`を返すようにする。
  4. `-initWithLayer:`を実装する。このイニシャライザでは直前の状態のレイヤが渡されます。プロパティをコピーします。

### アニメーションさせる方法

`CABasicAnimation`を利用します。

[code]

    var graph = AnimatableGraph()
    graph.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
    self.view.layer.addSublayer(graph)
    
    var animation = CABasicAnimation(keyPath: "degree")
    // 10秒間
    animation.duration = 10
    animation.repeatCount = 1
    // 9時の方向から時計回り1周
    animation.fromValue = 0.0
    animation.toValue = 360.0
    // アニメーション完了後の状態に関するおまじない
    animation.removedOnCompletion = false
    animation.fillMode = kCAFillModeForwards
    graph.addAnimation(animation, forKey: "key")
    
[/code]

ちょっと記述が煩雑なのが難ですね。


CC BY-SA 3.0
2015-03-13T18:09:44.317
7894
2015-03-13T18:37:11.423
2015-03-13T18:37:11.423
5337
5337
7875
answer