我正在为一个 UIView
子类设置边框宽度和颜色,方法如下:
- (void) setViewBorder
{
self.layer.borderColor = [UIColor greenColor].CGColor;
self.layer.borderWidth = 3.0f;
}
我的问题是: 我该如何为此添加动画效果?谢谢。
我正在为一个 UIView
子类设置边框宽度和颜色,方法如下:
- (void) setViewBorder
{
self.layer.borderColor = [UIColor greenColor].CGColor;
self.layer.borderWidth = 3.0f;
}
我的问题是: 我该如何为此添加动画效果?谢谢。
无论是borderColor
还是borderWidth
都是可以进行动画处理的属性,但由于您是在视图子类中而不是在UIView动画块中执行此操作,因此禁用了隐式动画(自动更改值时发生的动画)。
如果要对这些属性进行动画处理,则可以使用CABasicAnimation
进行显式动画。由于您正在对同一层上的两个属性进行动画处理,因此可以将它们都添加到一个动画组中,只需配置一次持续时间、时间控制等即可。请注意,显式动画仅为视觉效果,模型值(实际属性)在添加它们时不会更改。这就是为什么必须同时配置动画和设置模型值的原因。
CABasicAnimation *color = [CABasicAnimation animationWithKeyPath:@"borderColor"];
// animate from red to blue border ...
color.fromValue = (id)[UIColor redColor].CGColor;
color.toValue = (id)[UIColor blueColor].CGColor;
// ... and change the model value
self.layer.borderColor = [UIColor blueColor].CGColor;
CABasicAnimation *width = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
// animate from 2pt to 4pt wide border ...
width.fromValue = @2;
width.toValue = @4;
// ... and change the model value
self.layer.borderWidth = 4;
CAAnimationGroup *both = [CAAnimationGroup animation];
// animate both as a group with the duration of 0.5 seconds
both.duration = 0.5;
both.animations = @[color, width];
// optionally add other configuration (that applies to both animations)
both.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.layer addAnimation:both forKey:@"color and width"];
如果您查看CABasicAnimation文档中“设置插值值”部分,您会发现不必像我一样同时指定toValue和fromValue,因此代码可以稍微缩短。然而,为了清晰易懂(尤其是当您刚开始接触核心动画时),更加明确可能有助于您(和您的同事)理解代码。
layer
属性文档中,你可以看到视图是代理,并且不应更改代理。 - David RönnqvistactionForLayer:forKey:
中视图实际执行的操作,我能找到的最好答案是我的回答,它又引用了这个回答。但是,您可以进行自己的实验,并在动画块内外询问层代理(或直接询问视图)actionForLayer:forKey:
,看看您得到的响应是什么。我不记得在哪里正式记录过它。 - David Rönnqvist以下是对 @David 答案的快速解决方案:
let colorAnimation = CABasicAnimation(keyPath: "borderColor")
colorAnimation.fromValue = UIColor.red.cgColor
colorAnimation.toValue = UIColor.blue.cgColor
view.layer.borderColor = UIColor.blue.cgColor
let widthAnimation = CABasicAnimation(keyPath: "borderWidth")
widthAnimation.fromValue = 2
widthAnimation.toValue = 4
widthAnimation.duration = 4
view.layer.borderWidth = 4
let bothAnimations = CAAnimationGroup()
bothAnimations.duration = 0.5
bothAnimations.animations = [colorAnimation, widthAnimation]
bothAnimations.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
view.layer.add(bothAnimations, forKey: "color and width")
#keyPath(CALayer.borderColor)
代替 "borderColor"
。同样的,对于宽度也是如此... - Dean Kelly#keyPath
部分,因为它是编译安全的,如果属性名称发生变化,它将无法编译。 - Dean Kelly如果你只想让边框淡入,你也可以这样做:
UIView.transition(with: self, duration: 0.3, options: .transitionCrossDissolve, animations: {
self.layer.borderColor = UIColor.green.cgColor
self.layer.borderWidth = 3
}, completion: nil)
UIView.transition
而不是 UIViewPropertyAnimator
。 - inf1783UIView.transition
,因为它与 UIView.animate/UIViewPropertyAnimator
不兼容。也许你可以试试 ;) - inf1783//Create animation
CAKeyframeAnimation *colorsAnimation = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];
colorsAnimation.values = [NSArray arrayWithObjects: (id)[UIColor greenColor].CGColor,
(id)[UIColor yellowColor].CGColor, nil];
colorsAnimation.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.25],[NSNumber numberWithFloat:1.0], nil];
colorsAnimation.calculationMode = kCAAnimationLinear;
colorsAnimation.removedOnCompletion = NO;
colorsAnimation.fillMode = kCAFillModeForwards;
colorsAnimation.duration = 3.0f;
//Create animation
CAKeyframeAnimation *sizeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
sizeAnimation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:5.0], nil];
sizeAnimation.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],[NSNumber numberWithFloat:3.0], nil];
sizeAnimation.calculationMode = kCAAnimationLinear;
sizeAnimation.removedOnCompletion = NO;
sizeAnimation.fillMode = kCAFillModeForwards;
sizeAnimation.duration = 3.0f;
//Add animation
[yoursubview.layer addAnimation:colorsAnimation forKey:nil];
[yoursubview.layer addAnimation:sizeAnimation forKey:nil];