Re: Layer needs display if presentation layer moves?
Re: Layer needs display if presentation layer moves?
- Subject: Re: Layer needs display if presentation layer moves?
- From: Seth Willits <email@hidden>
- Date: Wed, 29 Jan 2014 11:44:38 -0800
It was an endless series of compounding errors yesterday for some reason, but I finally managed to get it to work. In retrospect it is easy, but not easily discoverable.
Here's the finished demo project:
http://www.sethwillits.com/temp/CATest_PresentationLayerTracking.zip
In this project a bunch of boxes fly around when you click on the view. Each box has a line drawn from the view's origin to the box's lower left corner, and the "tricky" part: those lines appropriately follow the boxes while they're animating.
I'll try to briefly describe this for posterity:
There's a ConnectionsLayer instance which has a nodeLayers property which is an array of all the of boxes' layers. On mouseDown in the view, each box's layer is randomly positioned, and then noteNodePositionsChanged is called on the connections layer. The ConnectionsLayer's drawInContext simply draws a line from the origin to the .position of the presentationLayer of each layer in nodeLayers. (The presentationLayer may be nil, so if it is, use the model layer's position.)
Now the "tricky" part is this:
- ConnectionsLayer has a private property: @property int nodePositionsDidChange;
- +needsDisplayForKey: returns YES for "nodePositionsDidChange" (calls super for anything else)
- noteNodePositionsChanged calls:
[self addAnimation:[CABasicAnimation animationWithKeyPath:@"nodePositionsDidChange"] forKey:@"animateForNodePositionsChange"];
The nodePositionsDidChange property itself is never set or get. It's simply there so that we can "animate" it, and Core Animation will recognize (via +needsDisplayForKey :) that while this property is animating, the layer should be redisplayed. Boom. (It's a bit voodoo that it can animate even though the value doesn't change at all, but there you go.)
The only "negative" part to this approach is that even if none of the boxes change positions, if noteNodePositionsChanged is called then it will redraw many times for whatever the duration of the animation is. So for efficiency's sake, noteNodePositionsChanged should only be called if a box's position actually did change. Ideally, we wouldn't need to call noteNodePositionsChanged manually at all.
Hopefully that helps anyone else looking for this in the future.
--
Seth Willits
_______________________________________________
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