在UIView动画期间,如何为UIView图层的子图层设置动画?

use*_*004 14 calayer uiview cabasicanimation uiviewanimation ios

在视图的UIView动画中,您可以通过包含在options参数中来为其布局的子视图设置动画.然而,当它们不是某个视图的背衬层时,我无法找到一种方法来设置其子层的动画.他们只是跳到位以匹配视图的新界限.因为我正在使用图层而不是视图,所以我似乎必须使用Core Animation而不是UIView动画,但我不知道如何(以及何时)这样做,使得图层动画与视图匹配动画.UIViewAnimationOptionLayoutSubviews[UIView animateWithDuration:delay:options:animations:completion:]

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

我通过向视图的图层添加CAShapeLayer创建了一个带有虚线边框的视图(请参阅此stackoverflow问题: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];
}
Run Code Online (Sandbox Code Playgroud)

这确实会使虚线边框生成动画,但它没有正确的计时功能和动画持续时间来匹配视图动画.此外,有时候,我们不希望虚线边框有动画,例如,当视图首先进行布局时,边框不应该从一些旧路径动画到新的正确路径; 它应该出现.

rin*_*aro 23

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

在- 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];
}
Run Code Online (Sandbox Code Playgroud)

  • 我不得不使用"position"属性来获取animationForKey,但除此之外它对我来说很有用! (4认同)
  • 谢谢,但我要提一下,这不适用于动画方法[U​​IView animateWithDuration:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:] (2认同)
  • @Eric你也可以使用`bounds.size`.一个快速断点和检查animationKeys告诉我有3个动画正在进行`[position,bounds.size,bounds.origin] (2认同)