【发布时间】:2014-03-08 10:37:39
【问题描述】:
我想设置CAShapeLayer 的strokeEnd 属性,没有默认动画,根本没有动画。我环顾四周试图找到如何做到这一点,但一切似乎都是关于如何为属性设置动画。
【问题讨论】:
标签: objective-c cocoa core-animation calayer
我想设置CAShapeLayer 的strokeEnd 属性,没有默认动画,根本没有动画。我环顾四周试图找到如何做到这一点,但一切似乎都是关于如何为属性设置动画。
【问题讨论】:
标签: objective-c cocoa core-animation calayer
在 Core Animations 术语中,动画的更通用术语是“动作”。例如,您可以看到 CAAnimation 符合 CAAction 协议。您还会看到禁用它们(禁用动画)时使用的术语“动作”。
有许多不同的方法可以改变图层的动作。其中许多在the discussion of the actionForKey: documentation on CALayer 中有很好的记录(摘录如下)。其中一些在子类化时更相关(您还可以在子类中覆盖 actionForKey: 以为新键添加更多隐式操作。
此方法按以下顺序搜索图层的关联动作:
- 如果层有一个委托并且该委托实现了访问层的过滤器方法,层调用该方法。代表必须执行以下操作之一:
- 返回给定键的操作对象。
- 如果它不处理该操作,则返回
nil。- 如果
NSNull对象不处理该操作,则返回该对象并且应终止搜索。- 图层在图层的
actions字典中查找。- 图层在 `style 字典中查找包含键的操作字典。
- 该层调用其 `defaultActionForKey: 方法来查找任何类定义的操作。
- 该层查找由 Core Animation 定义的任何隐式操作。
当您想要禁用动画时,最有趣的两种方法是(两种不同,因为它们用于稍微不同的事情):
CATransaction 禁用操作(以上未提及)@"strokeEnd" 键设置[NSNull null](上面的数字2)当您暂时想要完全禁用许多不同属性的操作,同时在其他地方仍然有动画时,使用事务来禁用动画是很好的选择。在代码中它看起来像这样:
[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
【讨论】:
您可以执行以下操作:
NSDictionary *actions = @{@"strokeEnd": [NSNull null]};
yourShapeLayer.actions = actions;
这将使它不会为属性设置动画。您还可以通过将其他属性添加到其中来指定不设置动画的其他属性:
NSDictionary *actions = @{@"strokeEnd": [NSNull null], @"position": [NSNull null], @"position": [NSNull null]};
【讨论】:
我认为一个不错的解决方案是创建一个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")
【讨论】: