uiview - Animate sine wave -
i'm trying animate sine wave in small frame, have searched lot on , on web, goal able reach it's draw static sine wave translate 1 side side, doens't want translation want animation draw of sinewave repetedaly animate in frame. can me? now:
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); }
then in uiviewcontroller this:
- (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); }]; }
but doesn't want translation, want continuous draw animation.
edit:
i have edit question using cadisplaylink suggest in comment:
// 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
and using in way in uiviecontroller:
mainview *view = [[mainview alloc] initwithframe:cgrectmake(0, 0, 200, 200)]; [self.view addsubview:view];
now problem drawing code draw little little segment move in sine wave, doesn't draw line, little segment, code can try , see problem, how can fix it?
create animatable phase
property (by declaring @dynamic
), drawrect:
method depends on; animate phase
infinite cabasicanimation
.
here great starting point custom animatable properties.
Comments
Post a Comment