0

UIView サブクラス (MyView と呼ばれる) の (void)drawRect:(CGRect)rect で単純なオブジェクトをアニメーション化する方法を理解しようとしています。私はコア アニメーションに不慣れで、このようなことを行う最善の方法がわかりません。

私は基本的に、タッチ座標をキャプチャして、動くオブジェクトとして表現できるようにしたいと考えています。NSMutableArray を使用してタッチをうまく保存できます。

Core Animation Programming Guide と Quartz2D Programming Guide を読むのに多くの時間を費やしました。サブレイヤーとレイヤーの使用に精通しているので、これがこのようなものに使用する必要がある場合は、正しい方向に向けてください。

私の主な目標は、タッチ ポイントをキャプチャして、移動可能な任意の形状として表現できるようにすることです。どんな助けでも大歓迎です。

#import "MyView.h"

@implementation MyView

@synthesize lastPoint;

NSMutableArray *myPoints;
CADisplayLink *theTimer;
float position = 0;

- (void) initializeTimer 
{   
    theTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateStuff:)];
    theTimer.frameInterval = 2; // run every other frame (ie 30fps)
    [theTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void) animateStuff:(NSTimer *)theTimer 
{
    position++;
    [self setNeedsDisplay];

}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code             
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)decoder
{
    if ((self = [super initWithCoder:decoder])) {

        // init array
        myPoints = [NSMutableArray array];

        position = 1;

        [self initializeTimer];

    }
    return self; 
}


- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{            
    // store point in array
    UITouch *touch = [touches anyObject];
    lastPoint = [touch locationInView:self];
    [myPoints addObject:[NSValue valueWithCGPoint:lastPoint]]; // store CGPoint as NSValue

}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);    
    CGContextSetFillColorWithColor(context, [UIColor orangeColor].CGColor);

    // draw all points in array
    NSUInteger pointCount = [myPoints count];
    for (int i = 0; i < pointCount; i++) {
        NSValue *v = [myPoints objectAtIndex:i];
        CGPoint p = v.CGPointValue;

        CGRect currentRect = CGRectMake(p.x-10+position, p.y-10, 20, 20);    
        CGContextAddRect(context, currentRect);  
    }
    CGContextDrawPath(context, kCGPathFillStroke);         
}

@end
4

2 に答える 2

1

drawRect でアニメーション化することは、絶対に、断固として間違った方法です。これにより、グラフィックス ハードウェアは毎回ビュー全体を再レンダリングする必要があります。それは非常に遅く、ぎくしゃくします。drawRect をできるだけトリガーしないようにします。

代わりに、なんらかの形式のアニメーションを使用する必要があります。多くのオプションがあります。

各オブジェクトをビューにして、animateWithDuration:completion: またはそのバリアントの 1 つなどの UIView アニメーション メソッドを使用できます。

レイヤーをアニメーション化し、それらのレイヤーをビューのサブレイヤーとして追加し、暗黙的なアニメーション (レイヤーの位置プロパティまたは他の「アニメーション化可能な」プロパティを変更するだけでシステムがアニメーション化する場所) を使用してそれらをアニメーション化することができます。変更) または明示的なアニメーション (さまざまなタイプの CAAnimation オブジェクトを作成し、それらをレイヤーに追加する場合)。

最後に、CAShapeLayer を使用して、レイヤーにインストールされているパスをアニメーション化できます。アニメーション ステップ間のパスに同じ数とタイプのコントロール ポイントを保持している限り、シェイプ レイヤーを使用して一度に多数のシェイプをアニメートできます。また、曲線を複雑な方法で変化させたり、その他の多くの興味深い効果をアニメーション化することもできます。CAShapeLayer 内で曲線をアニメーション化するということは、CGPath オブジェクトと CAAnimation オブジェクトの両方を使用することを意味します。

UIView アニメーションは最も使いやすく、パフォーマンスが最適化されています。ビュー アニメーションを使用してやりたいことを実行できる場合は、おそらく使用する必要があります。

次の複雑さのレベルは、暗黙的なレイヤー アニメーションです。

CAAnimation オブジェクトを使用した明示的なアニメーションは、最も複雑ですが、最も強力でもあります。

于 2012-09-07T01:44:34.313 に答える
0

本当に必要なのは、単純な CALayer を任意の形状 (たとえば、20x20 Rect) で描画することです。タッチが発生するたびに、位置を取得できます。そのレイヤーの位置を変更するだけです。それだけです。必要、ちょうど:

layer.position = newPosition;

そして、それは暗黙的にアニメーション化されます。

于 2012-09-01T22:20:11.827 に答える