可以为蒙版更改设置动画。
我更喜欢使用 CAShapeLayer 作为遮罩层。借助属性路径为蒙版更改设置动画非常方便。
在动画任何更改之前,将源的内容转储到实例 CGImageRef 中,并为动画创建一个新层。在动画期间隐藏原始图层并在动画结束时显示它。
以下是在属性路径上创建关键动画的示例代码。如果要创建自己的路径动画,请确保路径中的点数始终相同。
- (CALayer*)_mosaicMergeLayer:(CGRect)bounds content:(CGImageRef)content isUp:(BOOL)isUp {
CALayer* layer = [CALayer layer];
layer.frame = bounds;
layer.backgroundColor = [[UIColor clearColor] CGColor];
layer.contents = (id)content;
CAShapeLayer* maskLayer = [CAShapeLayer layer];
maskLayer.fillColor = [[UIColor blackColor] CGColor];
maskLayer.frame = bounds;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.path = ( isUp ? [self _maskArrowUp:-bounds.size.height*2] : [self _maskArrowDown:bounds.size.height*2] );
layer.mask = maskLayer;
CAKeyframeAnimation* ani = [CAKeyframeAnimation animationWithKeyPath:@"path"];
ani.removedOnCompletion = YES;
ani.duration = 0.3f;
ani.fillMode = kCAFillModeForwards;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
NSArray* values = ( isUp ?
[NSArray arrayWithObjects:
(id)[self _maskArrowUp:0],
(id)[self _maskArrowUp:-ceilf(bounds.size.height*1.2)],
nil]
:
[NSArray arrayWithObjects:
(id)[self _maskArrowDown:0],
(id)[self _maskArrowDown:bounds.size.height],
nil]
);
ani.values = values;
ani.delegate = self;
[maskLayer addAnimation:ani forKey:nil];
return layer;
}
- (void)_startMosaicMergeAni:(BOOL)up {
CALayer* overlayer = self.aniLayer;
CGRect bounds = overlayer.bounds;
self.firstHalfAni = NO;
CALayer* frontLayer = nil;
frontLayer = [self _mosaicMergeLayer:bounds
content:self.toViewSnapshot
isUp:up];
overlayer.contents = (id)self.fromViewSnapshot;
[overlayer addSublayer:frontLayer];
}