简体   繁体   English

如何在使用隐式动画为CALayer设置动画时继承动画属性

[英]How to inherit animation properties while animating CALayer with implicit animation

I am trying to animate a custom property on a CALayer with an implicit animation: 我试图使用隐式动画在CALayer上设置自定义属性的动画:

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

In -actionForKey: method I need to return the animation taking care of interpolating the values. 在-actionForKey:方法我需要返回动画,负责插值。 Of course I have to tell somehow the animation how to retrieve the other parameters for the animation (ie the duration and the timing 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 that? 有关如何实现这一点的任何想法? I tried looking for the animation in the layer properties but could not find anything interesting. 我尝试在图层属性中查找动画,但找不到任何有趣的内容。 I also have a problem with the layer animating since actionForKey: is called outside of animations. 我也有动画层动画的问题,因为actionForKey:在动画之外被调用。

I reckon that you have a custom layer with you custom property "myProperty" that you added to the backing layer of UIView - according to the Documentation UIView animation blocks does not support the animation of custom layer properties and states the need to use CoreAnimation: 我估计你有一个自定义属性,你自定义属性“myProperty”,你添加到UIView的支持层 - 根据文档UIView动画块不支持自定义图层属性的动画,并声明需要使用CoreAnimation:

Changing a view-owned layer is the same as changing the view itself, and any animations you apply to the layer's properties respect the animation parameters of the current view-based animation block. 更改视图拥有的图层与更改视图本身相同,并且应用于图层属性的任何动画都会遵循当前基于视图的动画块的动画参数。 The same is not true for layers that you create yourself. 对于您自己创建的图层,情况也是如此。 Custom layer objects ignore view-based animation block parameters and use the default Core Animation parameters instead. 自定义图层对象忽略基于视图的动画块参数,而是使用默认的Core Animation参数。

If you want to customize the animation parameters for layers you create, you must use Core Animation directly. 如果要为您创建的图层自定义动画参数,则必须直接使用Core Animation。

Further the documentation sates that UIView supports just a limited set of animatable properties which are: 此外,文档声称UIView仅支持一组有限的可动画属性:

  • frame
  • bounds 界限
  • center 中央
  • transform 转变
  • alpha α
  • backgroundColor 背景颜色
  • contentStretch contentStretch

Views support a basic set of animations that cover many common tasks. 视图支持一组涵盖许多常见任务的基本动画。 For example, you can animate changes to properties of views or use transition animations to replace one set of views with another. 例如,您可以对视图属性进行动画处理或使用过渡动画将一组视图替换为另一组视图。

Table 4-1 lists the animatable properties—the properties that have built-in animation support—of the UIView class. 表4-1列出了可动画的属性 - 具有内置动画支持的属性 - UIView类。

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

You have to create a CABasicAnimation for that. 你必须为此创建一个CABasicAnimation。

You can have sort of a workaround with CATransactions if you return a CABasicAnimation in actionForKey: like that 如果在actionForKey中返回CABasicAnimation,则可以使用CATransactions进行某种解决方法:就像那样

[UIView animateWithDuration:duration animations:^{
    [CATransaction begin];
    [CATransaction setAnimationDuration:duration];

    customLayer.myProperty = 1000; //whatever your property takes

    [CATransaction commit];
  }];

Just change your actionForKey: method to something like that 只需将actionForKey:方法更改为类似的方法即可

- (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 wan't to have a look: https://github.com/iMartinKiss/UIView-AnimatedProperty 如果你不想看看Github有什么东西: https//github.com/iMartinKiss/UIView-AnimatedProperty

I don't think you can access the duration if you use : 如果您使用以下内容,我认为您无法访问该持续时间

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

Other issue with your code is, the implementation of actionForKey: of UIView only returns a CAAnimation object if the code is called inside an animation block. 您的代码的其他问题是,如果在动画块中调用代码,则UIView的actionForKey:UIView的实现仅返回CAAnimation对象。 Otherwise it returns null to turn off animation. 否则返回null以关闭动画。 In your implementation, you always return a CAAnimation, hence changing to that property will always be animated. 在您的实现中,您始终返回CAAnimation,因此将始终对更改为该属性进行动画处理。

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 duration and timing function. 然后在actionForKey:方法中,使用[CATransaction animationDuration][CATransaction animationTimingFunction]来检索当前持续时间和计时功能。

The easiest way could be onother property in the your custom layer to set before myProperty . 最简单的方法可能是 myProperty 之前设置的自定义图层中的另一个属性。 like: 喜欢:

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, like duration , set in 如果你想获得参数,比如持续时间 ,请设置

 [UIView animateWithDuration:2.0f ... 

So in this case duration = 2.0f 所以在这种情况下持续时间= 2.0f

you can use CATransaction and valueForKey . 你可以使用CATransactionvalueForKey CATransaction should return the specific value of the context. CATransaction应返回上下文的特定值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM