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 protected])

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to