2

私は小さなフレームで正弦波をアニメーション化しようとしています.SOとWebでたくさん検索しましたが、到達できた唯一の目標は、一方の側からもう一方の側に変換される静的な正弦波を描くことです. 、しかし翻訳は必要ありません。フレーム内で繰り返しアニメーション化する正弦波のアニメーション描画が必要です。誰でも私を助けることができますか?これは私が今していることです:

Wave.h

@interface Wave : UIView

@end

Wave.m

@implementation Wave

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

- (void)drawRect:(CGRect)rect
{
[[UIColor colorWithRed:0 green:192/255.0 blue:255/255.0 alpha:1] set];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 1);
CGContextSetLineJoin(context, kCGLineJoinRound);
float width = rect.size.width;
const CGFloat amplitude = 30 / 4;
for(CGFloat x = 0; x < width; x += 0.5)
{
    CGFloat y = amplitude * sinf(2 * M_PI * (x / width) * 5) + 30;

    if(x == 0)
        CGContextMoveToPoint(context, x, y);
    else
        CGContextAddLineToPoint(context, x, y);
}

CGContextStrokePath(context);
}

次に、UIViewController でこれを行います。

- (void)viewDidLoad
{
self.wave = [[Wave alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-58, 205, 90, 200)];
[self.view addSubview:self.wave];

[self animateWave];
}

- (void)animateWave {
[UIView animateWithDuration:2.5 delay:0.0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionCurveLinear animations:^{
    self.wave.transform = CGAffineTransformMakeTranslation(+self.wave.frame.size.width/2, 0);
} completion:^(BOOL finished) {
    self.wave.transform = CGAffineTransformMakeTranslation(0, 0);
}];
}

しかし、私は翻訳が欲しいのではなく、連続描画アニメーションが欲しい.

編集:

コメントでCADisplayLinkの提案を使用して質問を編集しました:

// MainView.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "AnimationLayer.h"

@interface MainView : UIView
{
AnimationLayer *alayer;
}

@end

// MainView.m

#import "MainView.h"

@implementation MainView

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
    // Initialization code
    [self setBackgroundColor:[UIColor clearColor]];

}
return self;
}

- (void)didMoveToSuperview
{
if ([self superview])
{

    alayer = [[AnimationLayer alloc] init];
    alayer.frame = self.frame;
    [self.layer addSublayer:alayer];

}
}

@end

//  AnimationLayer.h

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface AnimationLayer : CALayer
{
CADisplayLink *displayLink;
}

@end

// AnimationLayer.m

#import "AnimationLayer.h"

static bool _running;

@implementation AnimationLayer

- (id)init
{
self = [super init];
if (self)
{
    displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
    [self setNeedsDisplayOnBoundsChange:YES];
}

return self;
}

static CGPoint lastPoint = {0, 0};

- (void)drawInContext:(CGContextRef)ctx
{
if (!_running)
{
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    _running = YES;
    return;
}

CGContextSetStrokeColorWithColor(ctx, [[UIColor blackColor] CGColor]);
CGRect rect = CGContextGetClipBoundingBox(ctx);
CGContextSetLineWidth(ctx, 2);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
float width = rect.size.width;
const CGFloat amplitude = 30 / 4;

CGContextMoveToPoint(ctx, lastPoint.x, lastPoint.y);
lastPoint.x += 0.5;
lastPoint.y = amplitude * sinf(2 * M_PI * (lastPoint.x / width) * 5) + 30;
CGContextAddLineToPoint(ctx, lastPoint.x, lastPoint.y);

CGContextStrokePath(ctx);

if (lastPoint.x == rect.size.width)
{
    [displayLink invalidate];
    _running = NO;
}
}

@end

uiviecontroller でこのように使用します。

MainView *view = [[MainView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[self.view addSubview:view];

今私の問題は、描画コードが正弦波で移動する小さなセグメントのみを描画することですが、線は描画しません。この小さなセグメントのみです。これはすべて私のコードなので、問題を試して確認できます。それを修正できますか?

4

1 に答える 1

0

メソッドが依存するアニメーション化可能なプロパティを作成しphaseます(宣言することにより@dynamic) 。次に、無限でdrawRect:アニメーション化します。phaseCABasicAnimation

カスタムのアニメート可能なプロパティの出発点としては、ここが最適です。

于 2013-07-22T10:37:51.260 に答える