当遇到圆角气泡时可以通过UIBezierPath
、CAShapeLayer
、mask
来实现对一个矩形视图的裁剪从而实现圆角气泡效果
首先要有一个矩形视图,初始状态应该是这样的
接下来在这个视图上开始用贝赛尔曲线画出来想要的图形,大概的示意图应该是这样的曲线
接下来就是
- 用贝塞尔曲线画出来上面的曲线
- 将曲线路径给CAShapeLayer来根据曲线path来显示裁剪一个layer
- 将这个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;
有几个注意点,我在第一次做的时候出现了下面的情况
把需要显示的部分镂空了。
之所以会出现这样的情况是因为
我在用UIBezierPath
的初始化方法时用错了。我把路径初始化时用的是这样的
UIBezierPath *path = [UIBezierPath bezierPathWithRect:processInfoView.bounds]
这样的话,初始化就给了一个路径,后面的曲线path和这个初始化出来的叠加起来了。
而path有一个属性是fillRule
这个属性的默认值是FillRuleEvenOdd
。EvenOdd是一个奇偶规则,奇数则显示,偶数不显示。当两条路径叠加在一起的时候。所以不显示。
关于mask,他就是一个layer,这个layer的透明度决定了layer的显示。不透明的内容可以显示,透明的不显示