Я использую CAShapeLayer
, чтобы замаскировать UIView
, установив self.layer.mask
для этого слоя формы.
Чтобы анимировать маску всякий раз, когда изменяется размер представления, я переписал -setBounds:
, чтобы анимировать путь слоя маски, если границы изменяются во время анимации.
Вот как я это реализовал:
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
CAPropertyAnimation *boundsAnimation = (CABasicAnimation *)[self.layer animationForKey:@"bounds"];
// update the mask
self.maskLayer.frame = self.layer.bounds;
// if the bounds change happens within an animation, also animate the mask path
if (!boundsAnimation) {
self.maskLayer.path = [self createMaskPath];
} else {
// copying the original animation allows us to keep all animation settings
CABasicAnimation *animation = [boundsAnimation copy];
animation.keyPath = @"path";
CGPathRef newPath = [self createMaskPath];
animation.fromValue = (id)self.maskLayer.path;
animation.toValue = (__bridge id)newPath;
self.maskLayer.path = newPath;
[self.maskLayer addAnimation:animation forKey:@"path"];
}
}
(Например, для self.maskLayer
установлено значение self.layer.mask)
My -createMaskPath
вычисляет CGPathRef, который я использую для маскировки вида. Я также обновляю путь маски в -layoutSubviews
.