贝塞尔曲线画圆角气泡.md

当遇到圆角气泡时可以通过UIBezierPathCAShapeLayermask来实现对一个矩形视图的裁剪从而实现圆角气泡效果

贝塞尔曲线画圆角气泡.md_第1张图片
image.png

首先要有一个矩形视图,初始状态应该是这样的

贝塞尔曲线画圆角气泡.md_第2张图片
image4.png

接下来在这个视图上开始用贝赛尔曲线画出来想要的图形,大概的示意图应该是这样的曲线

贝塞尔曲线画圆角气泡.md_第3张图片
image2.png

接下来就是

  1. 用贝塞尔曲线画出来上面的曲线
  2. 将曲线路径给CAShapeLayer来根据曲线path来显示裁剪一个layer
  3. 将这个layer作为view的mask来遮罩
    CGFloat corner = 5;
    CGFloat bottomMargin = 5;
    CGFloat arrowWidth = 5;
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    path.lineJoinStyle = kCGLineJoinRound;
    
    [path moveToPoint:CGPointMake(corner, 0)];
    [path addQuadCurveToPoint:CGPointMake(0, corner) controlPoint:CGPointMake(0, 0)];
    [path addLineToPoint:CGPointMake(0, processInfoViewHeight-bottomMargin-corner)];
    [path addQuadCurveToPoint:CGPointMake(corner, processInfoViewHeight-bottomMargin) controlPoint:CGPointMake(0, processInfoViewHeight-bottomMargin)];
    [path addLineToPoint:CGPointMake(processInfoViewWidth/2-arrowWidth/2, processInfoViewHeight-bottomMargin)];
    [path addLineToPoint:CGPointMake(processInfoViewWidth/2, processInfoViewHeight)];
    [path addLineToPoint:CGPointMake(processInfoViewWidth/2+arrowWidth/2, processInfoViewHeight-bottomMargin)];
    [path  addLineToPoint:CGPointMake(processInfoViewWidth-corner, processInfoViewHeight-bottomMargin)];
    [path addQuadCurveToPoint:CGPointMake(processInfoViewWidth, processInfoViewHeight-bottomMargin-corner) controlPoint:CGPointMake(processInfoViewWidth, processInfoViewHeight-bottomMargin)];
    [path addLineToPoint:CGPointMake(processInfoViewWidth, corner)];
    [path addQuadCurveToPoint:CGPointMake(processInfoViewWidth-corner, 0) controlPoint:CGPointMake(processInfoViewWidth, 0)];
    [path closePath];
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.frame = processInfoView.bounds;
    shapeLayer.path = path.CGPath;
    
    processInfoView.layer.mask = shapeLayer;

有几个注意点,我在第一次做的时候出现了下面的情况


贝塞尔曲线画圆角气泡.md_第4张图片
image3.png

把需要显示的部分镂空了。

之所以会出现这样的情况是因为
我在用UIBezierPath的初始化方法时用错了。我把路径初始化时用的是这样的

UIBezierPath *path = [UIBezierPath bezierPathWithRect:processInfoView.bounds]

这样的话,初始化就给了一个路径,后面的曲线path和这个初始化出来的叠加起来了。

而path有一个属性是fillRule这个属性的默认值是FillRuleEvenOdd。EvenOdd是一个奇偶规则,奇数则显示,偶数不显示。当两条路径叠加在一起的时候。所以不显示。

关于mask,他就是一个layer,这个layer的透明度决定了layer的显示。不透明的内容可以显示,透明的不显示

你可能感兴趣的:(贝塞尔曲线画圆角气泡.md)