CALayer 不透明度动画有效,但边界动画无效
Posted
技术标签:
【中文标题】CALayer 不透明度动画有效,但边界动画无效【英文标题】:CALayer opacity animation works but bounds animation doesn't 【发布时间】:2013-07-25 21:36:41 【问题描述】:我正在尝试为 CALayer 的边界设置动画,但它不起作用。代码如下:
class CircleView < UIIVew
def initWithFrame(frame)
super
# determine the dimensions
radius = (bounds.size.width < bounds.size.height ? bounds.size.width : bounds.size.height) / 2
# create the circle layer
@circle = CAShapeLayer.layer
@circle.bounds = bounds
@circle.path = UIBezierPath.bezierPathWithRoundedRect(bounds, cornerRadius: radius).CGPath
@circle.fillColor = UIColor.blueColor.CGColor
# add the circle to the view
self.layer.addSublayer(@circle)
shrink
self
end
private
# Applies the shrink animation to the provided circle layer.
def shrink
# determine the bounds
old_bounds = @circle.bounds
new_bounds = CGRectMake(old_bounds.size.width / 2, old_bounds.size.height / 2, 0, 0)
# animate the shrinking
animation = CABasicAnimation.animationWithKeyPath("bounds")
animation.fromValue = NSValue.valueWithCGRect(old_bounds)
animation.toValue = NSValue.valueWithCGRect(new_bounds)
animation.duration = 3.0
@circle.addAnimation(animation, forKey:"bounds")
# set the bounds so the animation doesn't bounce back when it's complete
@circle.bounds = new_bounds
end
# Applies the shrink animation to the provided circle layer.
def disappear
# animate the shirnk
animation = CABasicAnimation.animationWithKeyPath("opacity")
animation.fromValue = NSNumber.numberWithFloat(1.0)
animation.toValue = NSNumber.numberWithFloat(0.0)
animation.duration = 3.0
@circle.addAnimation(animation, forKey:"opacity")
# set the value so the animation doesn't bound back when it's completed
@circle.opacity = 0.0
end
end
如果我从 initWithFrame
方法中调用消失,动画效果很好。然而,调用收缩什么也不做。我做错了什么?
【问题讨论】:
【参考方案1】:那是因为您使用的是CAShapeLayer
。 path
独立于 bounds
,因此您必须单独对其进行动画处理。
我可以使用大致翻译成 Objective C 的代码版本来重现您的问题。当我将 shrink
method 更改为此时,它起作用了:
-(void)shrink
CGRect old_bounds = self.circle.bounds;
CGRect new_bounds = CGRectMake(old_bounds.size.width / 2, old_bounds.size.height / 2, 0, 0);
// bounds
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"bounds"];
animation.fromValue = [NSValue valueWithCGRect: old_bounds];
animation.toValue = [NSValue valueWithCGRect: new_bounds];
animation.duration = 3.0;
[self.circle addAnimation: animation forKey: @"bounds"];
// path
CGPathRef old_path = self.circle.path;
CGPathRef new_path = [UIBezierPath bezierPathWithRoundedRect:new_bounds cornerRadius:0].CGPath;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath: @"path"];
pathAnimation.fromValue = (__bridge id)(old_path);
pathAnimation.toValue = (__bridge id)(new_path);
pathAnimation.duration = 3.0;
[self.circle addAnimation: pathAnimation forKey: @"path"];
//set the value so the animation doesn't bound back when it's completed
self.circle.bounds = new_bounds;
self.circle.path = new_path;
从技术上讲,您甚至可能不必为边界设置动画。如果您在circle
层上设置了一个独特的backgroundColor
,您可以更轻松地进行一些实验,了解如何或多或少独立地设置和动画bounds
(例如,在您的原始代码中,您可以看到边界实际上是动画的,但路径保持不变。
【讨论】:
效果很好!谢谢您的帮助!我能够将边界动画排除在外。【参考方案2】:不了解 Ruby,我建议调整框架而不是边界。边界在 CALayers 自己的坐标系中,与图层本身在父级中的显示方式无关。
【讨论】:
Apple Docs: frame: 这个属性是不可动画的。您可以通过为 bounds 和 position 属性设置动画来获得相同的结果。 developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/… 抱歉,您目前正在使用边界来设置图层相对于其父级的原点。这只会影响其内容而不是图层本身 - 而框架可以满足您的需求。您链接的苹果文档表明该位置是可动画的。该位置相对于默认情况下为边界中心的锚点。要动画层的大小,请使用边界。 apple dev link with more info以上是关于CALayer 不透明度动画有效,但边界动画无效的主要内容,如果未能解决你的问题,请参考以下文章