Re: sync drawing an ever-increasing path
Re: sync drawing an ever-increasing path
- Subject: Re: sync drawing an ever-increasing path
- From: Roland King <email@hidden>
- Date: Wed, 24 Oct 2012 08:39:10 +0800
On 24 Oct, 2012, at 2:37 AM, David Duncan <email@hidden> wrote:
> On Oct 23, 2012, at 4:37 AM, Roland King <email@hidden> wrote:
>
>> I want to animate the drawing of CGPath in a UIView, so it looks as if it's being drawn. I have the UIView, I have the CGPath, I am able to split the CGPath at any point from 0 to 100% into that which should be drawn and that which shouldn't yet, that's all done, so I can, fairly efficiently, call -(CGPath)[ myObject fractionalPath:(CGFloat)fraction ] and get a path.
>
>
> You can do this with a CAShapeLayer by animating the strokeEnd property. Should be very simple to do, although if your path is very complex it may make more sense to break it into pieces and use multiple shape layers animated sequentially.
> --
> David Duncan
>
Thanks David, my shape is a bit complex for the strokeEnd property animation, I need to slowly and accurately 'trace' the outline of a path which has multiple elements and contains several closed paths. I already did the math to give me the first x% of the path, efficiently, even splitting any last bezier into a partial, so I'm happy with that bit, just needed to draw these partial and growing paths in sequence. Also I need the path to join correctly as it bends, so drawing it as one path, not different paths on different layers, is optimal.
So I made a custom CALayer, gave it a 'percentage' property, made that @dynamic. I set needsDisplayForKey: to return YES for @"percentage" so I get the redraw calls and implemented drawInContext: so that it fetches self.percentage, gets the path for that percentage and draws it. This works. The one thing I had trouble with was getting the animation to start and animate between whatever percentage was and whatever I set it to, the UIViewController just does layer.percentage=1 and expects that to animate. Eventually I found actionForKey: and overrode that method to return a CABasicAnimation .. like this
-(id<CAAction>)actionForKey:(NSString*)key
{
if( [ key isEqualToString:@"percentage" ] )
{
CABasicAnimation *anim = [ CABasicAnimation animationWithKeyPath:@"percentage" ];
anim.duration = 2.0f;
anim.fromValue = [ self.presentationLayer valueForKey:key ]; // <--- why oh why
return anim;
}
else
return [ super actionForKey:key ];
}
Two things I don't understand here.
First, why do I have to set the fromValue? I found without doing that, I don't get an animation, it just jumps instantly to the final point and draws the whole path? But the documentation for CABasicAnimation says that if fromValue, toValue and byValue are all nil, it should animate from the previous value of keypath to the new value, which is what I want, but doesn't do it. I got stuck on this for ages until I googled up an example showing how to get the current value off the presentation layer and set anim.fromValue, then it works.
Secondly, [ self.presentationLayer valueForKey:@"percentage" ] gives me the current value of percentage, which I use for fromValue, fortunately I don't need to set toValue, that it manages to do itself, but if I did want the 'new' value of percentage, how could I get it at that point? I've tried the model layer and everything else I can think of. Is the 'new' value of percentage available at all at the point of actionForKey being called?.
Or is actionForKey: the wrong place to return this animation?
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden