How to inherit animation properties when animating CALayer with implicit animation

I am trying to animate a custom property on CALayer with implicit animation:

[UIView animateWithDuration:2.0f animations:^{ self.imageView.myLayer.myProperty = 1; }]; 

In -actionForKey: method I need to return the animation, taking care of the interpolation of the values. Of course, I need to somehow tell the animation how to get other parameters for the animation (i.e. duration and synchronization function ).

 - (id<CAAction>)actionForKey:(NSString *)event { if ([event isEqualToString:@"myProperty"]) { CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"myProperty"]; [anim setFromValue:@(self.myProperty)]; [anim setKeyPath:@"myProperty"]; return anim; } return [super actionForKey:event]; } } 

Any idea on how to achieve this? I tried to find the animation in the layer properties, but could not find anything interesting. I also have a problem with layer animations, since actionForKey: is called outside of animations.

+7
ios core-animation calayer
source share
3 answers

I believe that you have a user level with your custom property "myProperty" that you added to the background layer of the UIView - according to the animation blocks of the UIView documentation, animation of the user properties of the layer is not supported and the need to use CoreAnimation is stated:

Changing the layer that belongs to the view coincides with changing the view itself, and any animations that you apply to the properties of the layers, the animation settings of the current animation block based on the view. The same does not apply to layers that you create yourself. Custom layer objects ignore view-based animation block options and use the default base animation options instead.

If you want to adjust the animation settings for the layers you create, you must use Core Animation directly.

The documentation further states that UIView only supports a limited set of animation properties which:

  • frame
  • Borders
  • center
  • convert
  • alpha
  • BackgroundColor
  • contentStretch

Views support a basic set of animations that span many common tasks. For example, you can animate changes to the properties of views, or use transitional animations to replace one set of views with another.

Table 4-1 lists the animation properties β€” properties that have native animation support β€” of the UIView class.

https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW12

To do this, you need to create a CABasicAnimation.

You might have some workaround with CATransactions if you return CABasicAnimation to actionForKey: for example,

 [UIView animateWithDuration:duration animations:^{ [CATransaction begin]; [CATransaction setAnimationDuration:duration]; customLayer.myProperty = 1000; //whatever your property takes [CATransaction commit]; }]; 

Just change the action actionForKey: action to something like this

 - (id<CAAction>)actionForKey:(NSString *)event { if ([event isEqualToString:@"myProperty"]) { return [CABasicAnimation animationWithKeyPath:event]; } return [super actionForKey:event]; } 

There is something in Github in case you don't want to watch: https://github.com/iMartinKiss/UIView-AnimatedProperty

+4
source share

I do not think you can access duration if you use:

 [UIView animateWithDuration:duration animations:^{ }]; 

Another problem with your code is that the implementation of actionForKey: from a UIView returns a CAAnimation if the code is called inside an animation block. Otherwise, it returns null to disable the animation. In your implementation, you always return CAAnimation, so changing this property will always be animated.

You should use this:

 [CATransaction begin]; [CATransaction setAnimationDuration:duration]; [CATransaction setAnimationTimingFunction:timingFunction]; customLayer.myProperty = 1000; //whatever your property takes [CATransaction commit]; 

Then, in your actionForKey: method, use [CATransaction animationDuration] and [CATransaction animationTimingFunction] to retrieve the current time and time function.

+1
source share

The easiest way may be in another property at your user level to set up to myProperty. as:

 self.imageView.myLayer.myTimingFunction = kCAMediaTimingFunctionEaseInEaseOut; self.imageView.myLayer.myProperty = 1; 

and

 -(id<CAAction>)actionForKey:(NSString *)event { if ([event isEqualToString:@"myProperty"]) { CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"myProperty"]; [anim setFromValue:@(self.myProperty)]; [anim setKeyPath:@"myProperty"]; [anim setTimingFunction:myTimingFunction]; return anim; } return [super actionForKey:event]; } } 

If you want to get parameters, for example duration , set

  [UIView animateWithDuration:2.0f ... 

So in this case duration = 2.0f

you can use CATransaction and the value ForKey . CATransaction should return a specific context value.

0
source share

All Articles