facebookarchive / pop

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

How do I reset layer rotation? #337

Closed sryze closed 7 years ago

sryze commented 7 years ago

I created a rotation animation like this:

POPBasicAnimation *a = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];
a.fromValue = @0;
a.toValue = @(DEGREES_TO_RADIANS(-38));
a.beginTime = CAMediaCurrentTime();
a.duration = 1;
[view.layer pop_addAnimation:a forKey:nil];

However, the next time the view appears it's already rotated. How do I reset the rotation back to 0?

I've already tried setting transform and affineTransform to the identity transform but that didn't work for some reason.

grp commented 7 years ago

Pop changes object properties over time. You can of course change those properties manually when Pop isn't animating them, before adding an animation or after it is finished or removed.

Assuming your propertyName is in this case kPOPLayerRotation, that will change view.layer.transform. Remove the animation and set it back to the default value, CATransform3DIdentity, to reset.

If the view is still appearing rotated, there are two possibilities. First, you may not be actually setting the property as you expect — maybe the view is unexpectedly nil at that point? Or, something might be setting the transform back to rotated, either an ongoing Pop animation or other code in your app.

sryze commented 7 years ago

You were right, it was a bug in my code. Thanks anyway!

sryze commented 7 years ago

Apparently I haven't fixed it as it's still not working.

I don't know what I'm doing wrong, I'm resetting the transform both inside the completion block and before the animation begins but the view is somehow rotated nevertheless. It's not nil, I checked that.

sryze commented 7 years ago

This seems to occur only if I cancel the animation before it begins (but is already added). If it's cancelled while executing or after completion everything works great...

I'm using pop_removeAllAnimations() to cancel all animations.

grp commented 7 years ago

I would suggest logging the transform when the view is appearing incorrectly. If the transform is non-identity at that point, it isn't being set correctly.

If it is identity, something else must be setting it back afterwards. To debug that, you could add a breakpoint on -[CALayer setTransform:].

sryze commented 7 years ago

When the animation is added to the layer the transform is identity. However, when inspecting the view in the view hierarchy debugger it's stretched out:

screen shot 2016-10-02 at 14 41 22

At that point transform is equal to:

(m11 = 0.78801065683364868, 
m12 = -0.6156613826751709, 
m13 = 0,
m14 = 0,
m21 = 0.6156613826751709, 
m22 = 0.78801065683364868, 
m23 = 0, 
m24 = 0, 
m31 = 0, 
m32 = 0, 
m33 = 1, 
m34 = 0, 
m41 = 0, 
m42 = 0, 
m43 = 0, 
m44 = 1)

This is how it normally looks (unrotated):

screen shot 2016-10-02 at 14 42 38

And this is how it should look when rotated:

screen shot 2016-10-02 at 14 45 21

I'm not an expert in transforms but to me it appears to be rotated along the wrong axis on the first (bugged) image. Any ideas why it might be? This is the only animation that changes its angle.

grp commented 7 years ago

Is that a different issue from your first one? I'm not sure how to match those screenshots up with what you said initially.

grp commented 7 years ago

In the first screenshot, I think the issue is that you are setting the frame on the layer, which (unlike the bounds) includes the transform. You can see in the inspector on the right how this causes the layer bounds to be squished in order to fit into the frame you set. Try setting the bounds and center directly rather than the frame when using a custom transform.

sryze commented 7 years ago

I'll try that, thanks.