【问题标题】:Animate CALayer mask change with fade effect使用淡入淡出效果动画 CALayer 蒙版更改
【发布时间】:2014-12-24 13:56:12
【问题描述】:

我有一个UIView,其中view.layer.mask 设置为CAShapeLayer 的一个实例。形状层包含一个路径,现在我想通过添加第二个具有奇偶规则的形状来为这个形状添加一个洞,并淡入这个洞的外观。

问题是添加到路径似乎不是可动画的:

[UIView animateWithDuration:2 animations:^() {
    CGPathAddPath(parentPath, nil, holePath);
    [v.layer.mask didChangeValueForKey:@"path"];
}];

我将如何制作动画?

【问题讨论】:

    标签: ios objective-c core-animation calayer


    【解决方案1】:

    经过一番折腾,找到了解决方法:

    1. 创建一个包含两个具有两个所需形状的子图层的图层,并将其用作蒙版
    2. 将第一个子层(无孔)的不透明度从 1 设置为 0。

    这是因为子 CAShapeLayer 实例似乎被用作联合。当你隐藏第一个没有洞的子图层时,只会露出洞,共享区域不会改变。

    CGMutablePathRef p = CGPathCreateMutable();
    
    // First path
    CGPathAddPath(p, nil, outerPath);
    CAShapeLayer *mask1 = [CAShapeLayer layer];
    mask1.path = p;
    
    // 2nd path with a hole
    CGPathAddPath(p, nil, innerPath);
    CAShapeLayer *mask2 = [CAShapeLayer layer];
    mask2.path = p;
    mask2.fillRule = kCAFillRuleEvenOdd;
    
    CGPathRelease(p);
    
    // Create actual mask that hosts two submasks
    CALayer *mask = [CALayer layer];
    [mask addSublayer:mask1];
    [mask addSublayer:mask2];
    myView.layer.mask = mask;
    mask.frame = v.layer.bounds;
    mask1.frame = mask.bounds;
    mask2.frame = mask.bounds;
    
    // ...
    
    // Hide mask #1
    CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"opacity"];
    a.fromValue = @1.0;
    a.toValue = @0.0;
    a.duration = 1.0;
    a.fillMode = kCAFillModeForwards; // Don't reset back to original state
    a.removedOnCompletion = NO;
    [mask1 addAnimation:a forKey:@"hideMask1"];
    

    【讨论】:

    • 这很聪明。做得好。 (投票)。你应该接受你自己的答案。
    【解决方案2】:

    您不能使用 UIView 动画来为 CALayers 设置动画。

    默认情况下,大多数图层属性更改都会进行动画处理(隐式动画)。我记得,形状层路径更改是一个例外。

    您需要创建一个 CAAnimation 对象,其中要设置动画的属性是遮罩层上的路径。

    但是,这可能不会产生您想要的效果。原因是当你改变形状层上的路径时,Core Animation 会尝试对路径形状的变化进行动画处理。此外,只有当起始路径和结束路径具有相同数量和类型的控制点时,路径更改才能正常工作。

    我不确定如何在不做大量工作的情况下实现 2 个不同蒙版之间的交叉淡入淡出。

    在我的脑海中,我能想到的唯一方法是使用更改的蒙版(可能使用核心图像过滤器)创建新视图外观的快照,然后进行交叉淡入淡出显示该快照的图层。交叉淡入淡出完成后,您将在不带动画的蒙版层中安装新路径,然后移除快照位图,显示下方的真实视图。

    可能有一种更简单的方法可以实现您所追求的目标,但我不知道那会是什么。也许为 SO 做出贡献的 CA 专家之一可以在这里插话。

    【讨论】:

    • 我觉得以这种方式为形状设置动画是行不通的,所以我找到了一种解决方法,使用子图层并更改不透明度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多