【问题标题】:Why addAnimation:forKey not working in viewDidLoaded为什么 addAnimation:forKey 在 vi​​ewDidLoaded 中不起作用
【发布时间】:2016-11-25 19:09:35
【问题描述】:

我有以下由 viewDidLoad 调用的方法。此方法是创建一个 CALayer 来显示图像。该层有一个掩码,其路径是我的私有方法创建的 UIBezierPath。我想让蒙版无限旋转,然后给蒙版添加一个 CABasicAnimation 对象。

- (void) createPathLmask
{
    // mask layer
    self.pathLayer                 = [CALayer layer];
    self.pathLayer.bounds          = CGRectMake(0.0, 0.0, 120, 120);

    CGPoint position = self.view.layer.position;
    position.y += 140;
    self.pathLayer.position        = position;
    self.pathLayer.backgroundColor = [UIColor redColor].CGColor;

    UIImage *backimage = [UIImage imageNamed:@"image2"];
    self.pathLayer.contents = (__bridge id)backimage.CGImage;
    self.pathLayer.contentsGravity = kCAGravityResizeAspectFill;

    // mask
    CAShapeLayer *mask = [CAShapeLayer layer];
    mask.bounds          = CGRectMake(0.0, 0.0, 120, 120);
    mask.position        = CGPointMake(60.0f, 60.0f);
    mask.contentsGravity = kCAGravityResizeAspectFill;
    mask.path            = [self createBezierPathInRect:mask.bounds].CGPath;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // rotate the mask repeatedly
        CABasicAnimation *animation = [CABasicAnimation animation];
        animation.keyPath = @"transform.rotation";
        animation.duration = 4.0f;
        animation.byValue  = @(M_PI * 2);
        animation.repeatCount = HUGE_VALF;
        [mask addAnimation:animation forKey:@"rotation_repeatedly"];
    });

    self.pathLayer.mask = mask;

    [self.view.layer addSublayer:self.pathLayer   ];
}

我发现旋转动画只有在我将 addAnimation:forKey 放入 dispatch_after 块并延迟 1 秒后才能工作。如果将这些代码移出块,则掩码将不会旋转。

所以在viewDidLoaded中给layer添加动画的时候肯定有什么东西没有准备好。我想知道什么还没准备好?是否有任何关于添加动画的合适机会的文档或说明?

【问题讨论】:

    标签: ios objective-c uiview core-animation calayer


    【解决方案1】:

    所以在viewDidLoaded中给layer添加动画的时候肯定有什么东西没有准备好

    正确。这对动画来说太早了。请记住,此时的视图仅存在,仅此而已;它甚至不是界面的一部分。您不能为不属于视图层次结构的视图设置动画。在这一点上,没有任何东西可以制作动画。

    视图首先成为第一次调用viewWillAppear 和第一次调用viewDidAppear 之间的接口的一部分。这就是“出现”的意思(与“加载”相对)的意思。

    【讨论】:

    • 非常感谢@matt 的回复。是的,你是对的,向图层添加动画的合适位置可以是 viewWillAppear 或 viewDidAppear。 addAnimation:forKey 的文档说这个 API 会将动画添加到图层的渲染树中。不知道有没有文档描述层(或者UIView的后端层)及其表现层和渲染层的生命周期?我从《View Controller Programming Guide》和《Core Animation》中都没有找到编程指南”
    • “描述层(或UIView的后端层)及其表示层和渲染层的生命周期的文档”我不知道您所说的“生命周期”是什么意思。你到底想知道什么?我想你总是可以读我的书:apeth.com/iOSBook/ch16.htmlapeth.com/iOSBook/ch17.html
    • 但是,我相信我确实回答了您的实际问题,不是吗?
    【解决方案2】:

    在 Apple 的网站 here 上有很棒的文档。简单地说:

    • ViewWillAppear - 在将视图控制器的视图添加到视图层次结构之前以及配置任何动画以显示视图之前调用此方法。您可以覆盖此方法以执行与显示视图相关的自定义任务。例如,您可以使用此方法更改状态栏的方向或样式,以与正在呈现的视图的方向或样式相协调。

    【讨论】:

    • 感谢您的回复。确实,您的链接对我很有用。至少,它可以是有助于理解深层机制的描述的一部分。但我不知道为什么有人投了反对票。让我再等一会儿,看看会不会有更多的解释。
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 2012-09-20
    • 2021-05-16
    • 2018-09-30
    • 1970-01-01
    相关资源
    最近更新 更多