2014-07-10 50 views
12

在视图的UIView动画中,您可以通过在[UIView animateWithDuration:delay:options:animations:completion:]的选项参数中包含UIViewAnimationOptionLayoutSubviews来为其子视图设置动画。然而,当他们不是某个视图的背景层时,我无法找到一种方式来为其布局子层;他们只是跳到位以匹配视图的新界限。由于我正在使用图层而不是视图,看起来我必须使用Core Animation而不是UIView动画,但我不知道如何(以及何时)这样做,以便图层动画可以匹配视图动画。如何在UIView动画过程中为UIView图层的子图层设置动画效果?

这是我的基本问题。如果你想知道我想要完成的具体事情,请阅读更多内容。

我已经通过向视图的图层添加一个CAShapeLayer创建了一个带虚线边框的视图(请参阅此堆栈溢出问题:Dashed line border around UIView)。我调整了CAShapeLayer的路径以匹配layoutSubviews中视图的边界。

这有效,但有一个化妆品问题:当视图的边界在UIView动画中(例如在旋转过程中)动画时,虚线边框跳转到视图的新边界,而不是平滑地将其作为视图动画动画的边界。也就是说,当视图动画时,虚线边框的右侧和底部不会分别与视图的右侧和底部保持贴合。 我怎样才能从CAShapeLayer的虚线边框在视图旁边制作动画?

我在做什么,到目前为止被附加CABasicAnimation到CAShapeLayer:

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    self.borderLayer.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; 
    self.borderLayer.frame = self.bounds; 

    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; 
    [self.borderLayer addAnimation:pathAnimation forKey:nil]; 
} 

这确实会导致虚线边框动画,但它不具备正确的计时功能和动画持续时间相匹配视图动画。另外,有时候,我们不希望虚线边框有动画,当视图首先进行布局时,边框不应该从某条旧路径移动到新的正确路径;它应该只出现。

回答

19

您可能已经找到了答案,但我最近也遇到类似的问题,因为解决了它,我会发布答案。

- layoutSubViews方法中,可以将当前动画UIView作为背景层的CAAnimation- animationForKey:方法。使用这种 ,您可以实现- layoutSubviews像:

- (void)layoutSubviews { 
    [super layoutSubviews]; 

    // get current animation for bounds 
    CAAnimation *anim = [self.layer animationForKey:@"bounds"]; 

    [CATransaction begin]; 
    if(anim) { 
     // animating, apply same duration and timing function. 
     [CATransaction setAnimationDuration:anim.duration]; 
     [CATransaction setAnimationTimingFunction:anim.timingFunction]; 

     CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; 
     [self.borderLayer addAnimation:pathAnimation forKey:@"path"]; 
    } 
    else { 
     // not animating, we should disable implicit animations. 
     [CATransaction disableActions]; 
    } 

    self.borderLayer.path = [UIBezierPath bezierPathWithRect:self.bounds].CGPath; 
    self.borderLayer.frame = self.bounds; 
    [CATransaction commit]; 
} 
+4

我不得不使用“位置”属性来获取animationForKey,但除此之外,对我来说真是棒极了! – Eric

+2

谢谢,但我应该提到,这不适用于动画方法[U​​IView animateWithDuration:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:] –

+1

@Eric您还可以使用'bounds.size'。如果我的UIView动画代码没有明确的键路径来引用,如快速断点和检查animationKeys告诉我有3个动画正在进行'[position,bounds.size,bounds.origin]' –