简体   繁体   English

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

[英]How do you animate the sublayers of the layer of a UIView during a UIView animation?

In a UIView animation for a view, you can animate its subviews being laid out by including UIViewAnimationOptionLayoutSubviews in the options parameter of [UIView animateWithDuration:delay:options:animations:completion:] . 在视图的UIView动画中,您可以通过在[UIView animateWithDuration:delay:options:animations:completion:]的options参数中包含UIViewAnimationOptionLayoutSubviews来为其布局的子视图设置[UIView animateWithDuration:delay:options:animations:completion:] However, I cannot find a way to animate it laying out its sublayers when they are not some view's backing layer; 然而,当它们不是某个视图的背衬层时,我无法找到一种方法来设置其子层的动画。 they would just jump into place to match the new bounds of the view. 他们只是跳到位以匹配视图的新界限。 Since I'm working with layers and not views, it seems like I have to use Core Animation instead of UIView animation, but I don't know how (and when) to do this such that the layer animation would match up to the view animation. 因为我正在使用图层而不是视图,所以我似乎必须使用Core Animation而不是UIView动画,但我不知道如何(以及何时)这样做,以便图层动画与视图匹配动画。

That's my basic question. 这是我的基本问题。 Read more if you want to know the concrete thing I'm trying to accomplish. 如果你想知道我想要完成的具体事情,请阅读更多内容。

I've created a view with a dotted border by adding a CAShapeLayer to the view's layer (see this stackoverflow question: Dashed line border around UIView ). 我通过向视图的图层添加CAShapeLayer创建了一个带有虚线边框的视图(请参阅此stackoverflow问题: UIView周围的虚线边框 )。 I adjust the path of the CAShapeLayer to match the bounds of the view in layoutSubviews . 我调整CAShapeLayer的路径以匹配layoutSubviews视图的边界。

This works, but there is one cosmetic issue: when the view's bounds is animated in a UIView animation (like during rotation), the dotted border jumps to the new bounds of the view instead of smoothly animating to it as the view animates its bounds. 这是有效的,但有一个美容问题:当视图的边界在UIView动画中动画时(如旋转期间),虚线边框跳转到视图的新边界,而不是在视图动画其边界时平滑地动画。 That is, the right and bottom parts of the dotted border do not respectively stay hugged to the right and bottom parts of the view as the view animates. 也就是说,当视图动画时,虚线边框的右边部分和底部部分不会分别保持与视图的右边部分和底部部分紧密相连。 How can I get the dotted border from the CAShapeLayer to animate alongside the view as it animates its bounds? 我怎样才能从CAShapeLayer中获取虚线边框,以便在视图动画边界时为视图设置动画?

What I'm doing so far is attaching a CABasicAnimation to the 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];
}

This does cause the dotted border to animate, but it does not have the right timing function and animation duration to match the view animation. 这确实会使虚线边框生成动画,但它没有正确的计时功能和动画持续时间来匹配视图动画。 Also, sometimes, we don't want the dotted border to animate like, when the view first does layout, the border should not animate from some old path to the new correct path; 此外,有时候,我们不希望虚线边框有动画效果,当视图首次进行布局时,边框不应该从一些旧路径动画到新的正确路径; it should just appear. 它应该出现。

You might have found the answer already, but I also faced similar problems recently, since solved it, I will post the answer. 你可能已经找到了答案,但最近我也遇到了类似的问题,因为解决了它,我会发布答案。

In - layoutSubViews method, you can get current UIView animation as backing layer's CAAnimation with - animationForKey: method. 在in - layoutSubViews方法中,您可以使用- animationForKey:方法获取当前UIView动画作为支持层的CAAnimation Using this, You can implement - layoutSubviews like: 使用此,您可以实现- 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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM