在 UIView 动画期间,如何为 UIView 层的子层设置动画? [英] How do you animate the sublayers of the layer of a UIView during a UIView animation?

查看:22
本文介绍了在 UIView 动画期间,如何为 UIView 层的子层设置动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在视图的 UIView 动画中,您可以通过将 UIViewAnimationOptionLayoutSubviews 包含在 [UIView animateWithDuration:delay:选项:动画:完成:].但是,当它们不是某些视图的支持层时,我无法找到一种方法来设置它的 子层 动画;他们只会跳到合适的位置以匹配视图的新边界.由于我使用的是图层而不是视图,似乎我必须使用核心动画而不是 UIView 动画,但我不知道如何(以及何时)执行此操作,以便图层动画与视图匹配动画.

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:]. 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.

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

我通过向视图层添加 CAShapeLayer 创建了一个带有虚线边框的视图(请参阅此 stackoverflow 问题:UIView 周围的虚线边框).我调整 CAShapeLayer 的路径以匹配 layoutSubviews 中的视图边界.

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). I adjust the path of the CAShapeLayer to match the bounds of the view in layoutSubviews.

这是可行的,但有一个外观问题:当视图的边界在 UIView 动画中设置动画时(例如在旋转期间),虚线边框会跳转到视图的新边界,而不是在视图动画时平滑地设置动画它的界限.也就是说,当视图动画时,虚线边框的右侧和底部不会分别保持紧贴视图的右侧和底部.如何从 CAShapeLayer 获取虚线边框以在视图动画其边界时与它一起动画?

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. 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?

到目前为止我正在做的是将 CABasicAnimation 附加到 CAShapeLayer:

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

- layoutSubViews 方法中,您可以使用- animationForKey: 获取当前UIView 动画作为支持层的CAAnimation方法.使用这个,你可以实现 - layoutSubviews 像:

In - layoutSubViews method, you can get current UIView animation as backing layer's CAAnimation with - animationForKey: method. Using this, You can implement - layoutSubviews like:

- (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];
}

这篇关于在 UIView 动画期间,如何为 UIView 层的子层设置动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆