2017-07-03 150 views
1

我設置與所有圓角路徑口罩視圖這樣的:動畫UIBezierPath所有圓角路徑與左上和右上圓角

CGFloat cornerRadius = CGRectGetHeight(self.myView.bounds)/2; 
CGSize cornerRadiusSize = CGSizeMake(cornerRadius, cornerRadius); 
CGRect bounds = self.myView.bounds; 

CAShapeLayer *maskLayer = [CAShapeLayer layer]; 

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:cornerRadiusSize]; 

maskLayer.path = maskPath.CGPath; 

self.myView.layer.mask = maskLayer; 

,看起來像這樣:

screenshot 1

我想它動畫與左上角和右上角的路徑圓角這樣的:

UIBezierPath *newMaskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:cornerRadiusSize]; 

CABasicAnimation *maskPathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; 

maskPathAnimation.duration = 0.3; 

maskPathAnimation.fromValue = (id)maskLayer.path; 
maskPathAnimation.toValue = (id)newMaskPath.CGPath; 

[maskLayer addAnimation:maskPathAnimation forKey:nil]; 

maskLayer.path = newMaskPath.CGPath; 

,看起來像這樣:

screenshot 2

但動畫是錯位的,它看起來像它的動畫一些角落的其他角落:

screenshot 3

+0

如果你刪除最後一個行會怎樣? 'maskLayer.path = newMaskPath.CGPath;' – chedabob

+0

它的動畫效果與之前相同,但在動畫結束時,蒙版會回到原始路徑。 –

+0

你需要設置填充模式和removeoncompletion:https://stackoverflow.com/questions/23806724/cabasicanimation-back-to-its-original-position-after-it-finish-its-1-cycle – chedabob

回答

0

我解決它通過創建遮罩手工使用此方法的路徑:

- (UIBezierPath *)getMaskPathForView:(UIView *)view withCorners:(UIRectCorner)corners { 

    CGSize size = view.bounds.size; 
    CGFloat cornerRadius = size.height/2; 

    UIBezierPath *maskPath = [UIBezierPath bezierPath]; 

    // top left 
    if (corners & UIRectCornerTopLeft) { 
     [maskPath moveToPoint:CGPointMake(0, cornerRadius)]; 
     [maskPath addQuadCurveToPoint:CGPointMake(cornerRadius, 0) controlPoint:CGPointZero]; 
    } else { 
     CGPoint topLeftCornerPoint = CGPointZero; 

     [maskPath moveToPoint:topLeftCornerPoint]; 
     [maskPath addQuadCurveToPoint:topLeftCornerPoint controlPoint:topLeftCornerPoint]; 
    } 

    // top right 
    if (corners & UIRectCornerTopRight) { 
     [maskPath addLineToPoint:CGPointMake(size.width - cornerRadius, 0)]; 
     [maskPath addQuadCurveToPoint:CGPointMake(size.width, cornerRadius) controlPoint:CGPointMake(size.width, 0)]; 
    } else { 
     CGPoint topRightCornerPoint = CGPointMake(size.width, 0); 

     [maskPath addLineToPoint:topRightCornerPoint]; 
     [maskPath addQuadCurveToPoint:topRightCornerPoint controlPoint:topRightCornerPoint]; 
    } 

    // bottom right 
    if (corners & UIRectCornerBottomRight) { 
     [maskPath addLineToPoint:CGPointMake(size.width, size.height - cornerRadius)]; 
     [maskPath addQuadCurveToPoint:CGPointMake(size.width - cornerRadius, size.height) controlPoint:CGPointMake(size.width, size.height)]; 
    } else { 
     CGPoint bottomRightCornerPoint = CGPointMake(size.width, size.height); 

     [maskPath addLineToPoint:bottomRightCornerPoint]; 
     [maskPath addQuadCurveToPoint:bottomRightCornerPoint controlPoint:bottomRightCornerPoint]; 
    } 

    // bottom left 
    if (corners & UIRectCornerBottomLeft) { 
     [maskPath addLineToPoint:CGPointMake(cornerRadius, size.height)]; 
     [maskPath addQuadCurveToPoint:CGPointMake(0, size.height - cornerRadius) controlPoint:CGPointMake(0, size.height)]; 
    } else { 
     CGPoint bottomLeftCornerPoint = CGPointMake(0, size.height); 

     [maskPath addLineToPoint:bottomLeftCornerPoint]; 
     [maskPath addQuadCurveToPoint:bottomLeftCornerPoint controlPoint:bottomLeftCornerPoint]; 
    } 

    [maskPath closePath]; 

    return maskPath; 
} 

like t他:

CAShapeLayer *maskLayer = [CAShapeLayer layer]; 

UIBezierPath *maskPath = [self getMaskPathForView:self.myView withCorners:UIRectCornerAllCorners]; 

maskLayer.path = maskPath.CGPath; 

self.myView.layer.mask = maskLayer; 

和:

UIBezierPath *newMaskPath = [self getMaskPathForView:self.myView withCorners:UIRectCornerTopLeft | UIRectCornerTopRight]; 

CABasicAnimation *maskPathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; 

maskPathAnimation.duration = 0.3; 

maskPathAnimation.fromValue = (id)maskLayer.path; 
maskPathAnimation.toValue = (id)newMaskPath.CGPath; 

[maskLayer addAnimation:maskPathAnimation forKey:nil]; 

maskLayer.path = newMaskPath.CGPath;