更改没有动画的CAShapeLayer

时间:2014-02-10 21:31:22

标签: objective-c cocoa core-animation calayer

我想在没有默认动画的情况下设置strokeEnd的{​​{1}}属性,根本没有动画。我环顾四周试图找到如何做到这一点,但一切似乎都是关于如何动画属性。

3 个答案:

答案 0 :(得分:39)

在Core Animations术语中,动画的更通用术语是“动作”。例如,您可以看到CAAnimation符合CAAction协议。您还会看到禁用它们时使用的术语“操作”(禁用动画)。

有许多不同的方法可以更改图层的操作。其中许多都在the discussion of the actionForKey: documentation on CALayer中得到了很好的记录(摘录如下)。其中一些在子类化时更相关(并且您还可以在子类中覆盖actionForKey:以为新键添加更多隐式操作。

  

此方法按以下顺序搜索图层的关联操作:

     
      
  1. 如果图层具有委托并且该委托实现了访问图层的过滤器方法,则图层将调用该方法。代表必须执行以下操作之一:      
        
    • 返回给定密钥的操作对象。
    •   
    • 如果不处理此操作,请返回nil
    •   
    • 如果NSNull对象未处理该操作,则返回该对象,并且应终止搜索。
    •   
  2.   
  3. 图层在图层的actions字典中查找。
  4.   
  5. 该图层在`样式字典中查找包含密钥的操作字典。
  6.   
  7. 该层调用其`defaultActionForKey:方法来查找任何类定义的操作。
  8.   
  9. 该图层查找Core Animation定义的任何隐式动作。
  10.   

当您想要禁用动画时,最有趣的两种方式是(两种不同,因为它们用于稍微不同的事情):

  1. 使用CATransaction(上面未提及)
  2. 禁用操作
  3. 为操作词典中的[NSNull null]键设置@"strokeEnd"(上面的数字2)
  4. 禁用操作

    当您暂时想要为多个不同的属性完全禁用操作,同时在其他地方仍然有动画时,使用事务来禁用动画是很好的。在代码中,它看起来像这样:

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    // change your property here 
    yourShapeLayer.strokeEnd = 0.7;
    [CATransaction commit]; // animations are disabled until here...
    

    更改动作词典

    您可以通过修改图层操作字典来永久更改一个或多个键的默认动画。设置[NSNull null]意味着不应该有动画,并且图层应该停止在别处寻找默认动画。您还可以使用它来添加可动画的属性。使用动作字典删除动画如下所示:

    yourShapeLayer.actions = @{@"strokeEnd": [NSNull null]};
    yourShapeLayer.strokeEnd = 0.7; // this won't have an animation
    

答案 1 :(得分:2)

您可以执行以下操作:

NSDictionary *actions = @{@"strokeEnd": [NSNull null]};
yourShapeLayer.actions = actions;

这将使它不会为该属性设置动画。您还可以通过将其添加到此处来指定其他属性以使其无法动画:

NSDictionary *actions = @{@"strokeEnd": [NSNull null], @"position": [NSNull null], @"position": [NSNull null]};

答案 2 :(得分:0)

我认为一个不错的解决方案是创建一个CABasicAnimation(keyPath: "strokeEnd")并将持续时间设置为很小的值。这是一个示例:

let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.toValue = someValue
basicAnimation.duration = animated ? 2.0 : 0.01
basicAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

basicAnimation.fillMode = kCAFillModeForwards
basicAnimation.isRemovedOnCompletion = false

// Apply the animation
circleProgress.add(basicAnimation, forKey: "progress")