facebookarchive / pop

An extensible iOS and OS X animation library, useful for physics-based interactions.
Other
19.66k stars 2.88k forks source link

Improve support for 3rd party animatable properties #68

Open hfossli opened 10 years ago

hfossli commented 10 years ago

Hi

I have a couple of classes and components I very much would like to integrate with Pop. I think it would be awesome to share my latest doings with everyone.

My suggested course of action

  1. Create a new project with a podspec named "+Pop"
  2. Write a class named "POPAnimatableProperty+"
  3. Define all animatable properties in header e.g. "kPOPView"
  4. In some way declare all the POPAnimatableProperty so that it is accessible via +[POPAnimatableProperty propertyWithName:]

I'm not quite sure about how to do listpoint 4.

The general question is: How should 3rd party libraries go about integrating with Pop? Some guidelines along the lines of this http://promisekit.org/#adding-promises-to-third-party-libraries would be great!

kimon commented 10 years ago

Looking forward to your writeup. If you'd like to add to the default list of properties provided by POP, here is one user-submitted example: https://github.com/facebook/pop/commit/43a10eee86d1a2ec3ad5617838985ed60e2dda57.

If the property is specific to one of your classes, I would suggest a category extension where you can create and optionally cache your definition. eg

@interface POPAnimatableProperty (MyExtension)
+ (POPAnimatableProperty +)myProperty;
@end

Let me know if you have more questions.

hfossli commented 10 years ago

I've created an extension as you suggested. This works fine for most of the code.

Though there is one problem: One of the properties on my class is a struct. I would like to animate this struct so I've written an NSValue-category which allows me to store those value. When setting the toValue on the animation it throws an exception.

2014-05-13 16:24:04.445 AGGeometryKit+Pop[63142:60b] *** Terminating app due to uncaught exception 'Unsuported value', reason: 'Animating NSConcreteValue values is not supported'
*** First throw call stack:
(
    0   CoreFoundation                      0x01c991e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x01a188e5 objc_exception_throw + 44
    2   CoreFoundation                      0x01c98fbb +[NSException raise:format:] + 139
    3   AGGeometryKit+Pop                   0x0002795a _Z8POPUnboxP11objc_objectR12POPValueTypeRjb + 570
    4   AGGeometryKit+Pop                   0x00041580 -[POPPropertyAnimation setToValue:] + 160

It does not seem straight forward plug in a custom NSValue with POP, unfortunately...

hfossli commented 10 years ago

As a hack I could always store the values in a CATransform3D, but that just feels wrong...

hfossli commented 10 years ago

@kimon Could this be reopened?

grp commented 10 years ago

Right now, Pop only supports animating a subset of structure types, generally the ones included with the system frameworks. I'd file a new issue for supporting additional or arbitrary structure types.

A workaround for now would be to use multiple animations, each with an animatable property that affects one element of your custom structure type. As long as the spring constant / timing function is the same for each animation, they will all run together.

hfossli commented 10 years ago

@grp Yep, that is what I have currently done in https://github.com/hfossli/AGGeometryKit-POP/blob/master/Source/POPAnimatableProperty%2BAGGeometryKit.m

Seems to work allright. I do think the POPCGUtils.h should be public and not private as it is today. Since values_from_point and values_to_point could not only be helpful, but also avoid too loose coupling when writing readBlock and writeBlock in a custom POPAnimatableProperty.

aleclarson commented 10 years ago

I think @hfossli is right when he suggests POPCGUtils.h should be public. The POPCGColor____ methods are valuable for my UILabel.textColor custom animatable property.

kimon commented 10 years ago

Okay :) We wanted to start with the smallest of footprints. Reopening to investigate based on user demand.

antoinelamy commented 10 years ago

I am not sure this is the correct place to talk about it but I am taking a chance. What I want to do is to animate the properties of a custom object and instead of creating individual animations for each properties, I want to be able to pass my entire object as a toValue.

Right now, the library forbid me doing that by raising an exception Animating PPCustomObject values is not supported. By digging a little bit, it seems that the toValue need to be vectorized with the POPVector class. I do not understand this limitation because for a custom property to be animated, it is already required to supply a readBlock that kind of do just that. Why not calling the readBlock on a custom property animation and use the returned array to create a vector?

leverdeterre commented 10 years ago

Hi everybody, i'have a pull request on POP that can improve that. https://github.com/facebook/pop/pull/89

This pull request provide a better understand of the API by using methods :

+ (id)propertyWithCustomName:(NSString *)name;
+ (id)propertyWithCustomName:(NSString *)name initializer:(void (^)(POPMutableAnimatableProperty *prop))block;
antoinelamy commented 10 years ago

@leverdeterre, these new methods seems nice but do not address my point, which is about setting a custom class as a toValue

ghost commented 9 years ago

Thank you for reporting this issue and appreciate your patience. We've notified the core team for an update on this issue. We're looking for a response within the next 30 days or the issue may be closed.