2012-10-09 10 views
6

私は、ユーザーがボタンを押すと、一連の線が画面に描画され、ユーザーはリアルタイムで描画された線を見ることができます(ほぼアニメーションのような) 。図面アニメーション

私のコードは次のようなもの(簡素化されました)になります。描画されるまで、とすぐにユーザーがボタンを押すと

1)UIThreadブロック:

UIGraphicsBeginImageContext(CGSizeMake(300,300)); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

for (int i = 0; i < 100; i++) { 
    CGContextMoveToPoint(context, i, i); 
    CGContextAddLineToPoint(context, i+20, i+20); 
    CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]); 
    CGContextStrokePath(context); 
} 

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

UIGraphicsEndImageContext(); 

を私の問題は、ということです完了しました。

2)私は一度に1つずつ画面に線を描くことができません - 私はUIImageをループ内に直接設定しようとしましたが、ループ内にレイヤーコンテンツを設定しようとしました。

これらの問題を回避するにはどうすればよいですか?

+0

これは役に立ちますか? http://stackoverflow.com/questions/9245954/mo​​ving-an-image-along-a-series-of-cgpoints –

+0

どのような遅延が欲しいですか? – nielsbot

+0

カスタマイズ可能な遅延が良い - 私はロブが私が探していたと思った...あなたの助けに感謝! – HHHH

答えて

16

あなたは「アニメーションのように」と言います。なぜ実際のアニメーションをしないのですか?Core Graphics 'CABasicAnimation?あなたは本当に一連の行としてそれを表示する必要がありますか、または適切なアニメーションは大丈夫ですか?

あなたがラインの実際の描画をアニメーション化する場合は、あなたが何か行うことができます:

#import <QuartzCore/QuartzCore.h> 

- (void)drawBezierAnimate:(BOOL)animate 
{ 
    UIBezierPath *bezierPath = [self bezierPath]; 

    CAShapeLayer *bezier = [[CAShapeLayer alloc] init]; 

    bezier.path   = bezierPath.CGPath; 
    bezier.strokeColor = [UIColor blueColor].CGColor; 
    bezier.fillColor  = [UIColor clearColor].CGColor; 
    bezier.lineWidth  = 5.0; 
    bezier.strokeStart = 0.0; 
    bezier.strokeEnd  = 1.0; 
    [self.view.layer addSublayer:bezier]; 

    if (animate) 
    { 
     CABasicAnimation *animateStrokeEnd = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
     animateStrokeEnd.duration = 10.0; 
     animateStrokeEnd.fromValue = [NSNumber numberWithFloat:0.0f]; 
     animateStrokeEnd.toValue = [NSNumber numberWithFloat:1.0f]; 
     [bezier addAnimation:animateStrokeEnd forKey:@"strokeEndAnimation"]; 
    } 
} 

を次にあなたがしなければならないすべては、例えば、あなたのラインのUIBezierPathを作成します

- (UIBezierPath *)bezierPath 
{ 
    UIBezierPath *path = [UIBezierPath bezierPath]; 

    [path moveToPoint:CGPointMake(0.0, 0.0)]; 

    [path addLineToPoint:CGPointMake(200.0, 200.0)]; 

    return path; 
} 

必要に応じて、複数の行を1つのパスにまとめることができます。

- (UIBezierPath *)bezierPath 
{ 
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    CGPoint point = self.view.center; 

    [path moveToPoint:CGPointMake(0, self.view.frame.size.height/2.0)]; 

    for (CGFloat f = 0.0; f < M_PI * 2; f += 0.75) 
    { 
     point = CGPointMake(f/(M_PI * 2) * self.view.frame.size.width, sinf(f) * 200.0 + self.view.frame.size.height/2.0); 
     [path addLineToPoint:point]; 
    } 

    return path; 
} 

これらは、メインスレッドをブロックしません。

ところで、CoreGraphics.frameworkをターゲットのBuild SettingsLink Binary With Librariesの下に追加する必要があります。

+1

それは素晴らしいです - ありがとう! 別の質問 - 私は[path addLineToPoint]を何度も(おそらく1000+)呼び出しています。あなたのメソッドを実装した後、私のアプリケーションとそれが実行されているデバイスが極端に遅く/かすれになります。私はアプリケーションのプロファイリングを行い、膨大な量のCPUを使用しているようには見えません - なぜこれがどうなるのか分かりますか? – HHHH

+0

@HHHH私はこれがデバイスに課税されると容易に想像することができました。たとえば、毎秒30本の線分を超えるようになると、アプリがアニメーションに追いつくのが難しくなります。私はカットオフがどこにあるのかわかりません(30 /秒?60?100?分かりません)。しかし、ある時点では、与えられたフレームのパスを描くのに要する時間アニメーションは、各フレームが長くかかる。そして、アニメーションが1秒間に30フレームよりもずっと遅くなると、それはもっとぎこちなくなります。あなたは何とか1秒間に描画する必要のある線分の数を減らさなければなりません。一口。 – Rob

+1

@HHHHおそらく、アニメーションの長さを_x/y_に設定することができます。ここで、_x_は線分の数です。_y_はサポートする秒単位のセグメント数です(これはおそらく実験したい数字ですあなたが何かジャーキネスなしで何とか離れていくことができるかを理解するために、おそらく30または60または100か...)。 – Rob