我有UIView
,view.layer.mask
设置为CAShapeLayer
的实例。形状图层包含一个路径,现在我想通过添加具有偶数/奇数规则的第二个形状为此形状添加一个孔,并且淡入该孔的外观。
问题是添加到路径似乎不具有动画效果:
[UIView animateWithDuration:2 animations:^() {
CGPathAddPath(parentPath, nil, holePath);
[v.layer.mask didChangeValueForKey:@"path"];
}];
我该如何设置动画?
答案 0 :(得分:5)
经过一番摆弄后,找到了解决方法:
这是有效的,因为子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"];
答案 1 :(得分:1)
您无法使用UIView动画为CALayers制作动画。
默认情况下,大多数图层属性更改都会执行动画(隐式动画)。我记得,形状层路径变化是一个例外。
您需要创建一个CAAnimation对象,其中您要设置动画的属性是遮罩层上的路径。
然而,这可能不会给你想要的效果。原因是当您更改形状图层上的路径时,Core Animation会尝试为路径形状的更改设置动画。此外,只有当起始路径和结束路径具有相同数量和类型的控制点时,路径更改才能正常工作。
我不确定你如何在没有大量工作的情况下实现两种不同面具之间的交叉淡入淡出。
在我的脑海中,我能想到的唯一方法是使用更改的蒙版(可能使用Core Image过滤器)创建新视图外观的快照,然后进行交叉淡入淡出显示该快照的图层。交叉渐变完成后,您可以在没有动画的情况下在遮罩层中安装新路径,然后移除快照位图,从而显示下面的真实视图。
可能有一种更简单的方法可以实现您的目标,但我不知道会是什么。也许其中一位为SO做出贡献的CA专家可能会在这里发声。