为视图的遮罩设置动画

bis0qfac  于 2022-10-23  发布在  Swift
关注(0)|答案(1)|浏览(147)

我想使用蒙版来实现这样的效果,即视图的可见部分随着蒙版的移动而改变。

,这是我的演示代码:

- (void)drawLayer{
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    self.maskLayer = maskLayer;
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.underView.bounds];
    CGRect frame = CGRectMake(-4, -5, (self.underView.frame.size.width+8) *0.5, self.underView.frame.size.height+10);
    UIBezierPath *topPath = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:frame.size.height *0.5];
    NSLog(@"maskLayerframe:%@",NSStringFromCGRect(frame));
    [path appendPath:topPath];
    maskLayer.path = path.CGPath;
    maskLayer.fillRule = kCAFillRuleEvenOdd;
    self.underView.layer.mask = maskLayer;
}
///animation
/// - Parameter swipeToRight: Whether to slide to the right
- (void)startAnimation:(BOOL)swipeToRight{
    CGFloat x = swipeToRight? self.underView.bounds.size.width *0.5-4:-4;
    CGRect frame = CGRectMake(x, -5, (self.underView.frame.size.width+8) *0.5, self.underView.frame.size.height+10);
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.underView.bounds];
    UIBezierPath *topPath = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:frame.size.height *0.5];
    [path appendPath:topPath];
    maskLayer.path = path.CGPath;
    maskLayer.fillRule = kCAFillRuleEvenOdd;
    [CATransaction begin];
    [CATransaction setDisableActions:NO];
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [CATransaction setAnimationDuration:0.5];
    self.maskLayer.frame = frame;
    [CATransaction commit];
}

但最终的动画是这样的,我不知道它出了什么问题,有人能告诉我吗?
动画前

右侧动画

动画从左至左

t3psigkw

t3psigkw1#

我找到了正确的实现方式~

- (void)startAnimation:(BOOL)swipeToRight{
    CGFloat x = swipeToRight? self.underView.bounds.size.width *0.5-4:-4;
    CGRect frame = CGRectMake(x, -4, (self.underView.frame.size.width+8) *0.5, self.underView.frame.size.height+8);
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.underView.bounds];
    UIBezierPath *topPath = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:frame.size.height *0.5];
    [path appendPath:topPath];
    maskLayer.path = path.CGPath;
    maskLayer.fillRule = kCAFillRuleEvenOdd;
    CABasicAnimation * basicAni = [CABasicAnimation animationWithKeyPath:@"path"];
    basicAni.fromValue = (__bridge id _Nullable)(self.maskLayer.path);
    basicAni.toValue = (__bridge id _Nullable)(maskLayer.path);
    basicAni.duration = 0.4;
    basicAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.underView.layer.mask addAnimation:basicAni forKey:@"path"];

    [CATransaction begin];
    [CATransaction setDisableActions:true];
    self.maskLayer.path = maskLayer.path;
    [CATransaction commit];
}

相关问题