小试牛刀
效果图是一个圆角矩形加一个尖角三角形,我称之为尖角矩形,如下图所示
直接要设计师提供一个切图当然是非常简单的,而且毫无难度。
但是刚好前两天看到一个效果,使用UIBezierPath画的一个下拉刷新的效果,这会想想是否能不用图片,使用UIBezierPath来画这个效果。
说干就干。
背景区域整体大小为,宽140,高50,尖角区域长度为20
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 0)];
[path addLineToPoint:CGPointMake(0, 25)];
[path addLineToPoint:CGPointMake(20, 50)];
[path addLineToPoint:CGPointMake(140, 50)];
[path addLineToPoint:CGPointMake(140, 0)];
[path closePath];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.path = path.CGPath;
layer.fillColor = UIColorFromRGB(0xFFEEE8).CGColor;
[rightBgView.layer insertSublayer:layer atIndex:0];
轻轻松松,效果实现。
进阶效果
经过初级实验,使用UIBezierPath绘制不规则图形还蛮简单,有一个复杂的效果,也考虑自己绘制。效果图如下
根据和设计师沟通,得知右边为一个圆角矩形,左下角为一个不规则图形,类似一个矩形,裁切掉一个椭圆后剩下的一个边角(设计师画的一个三角形,然后将一条边拉成弧形,如下图所示)
既然拆分成圆角矩形和另外一个不规则图形,就使用两个UIBezierPath来分别绘制,第一步,圆角矩形,这个很容易
// 根据内容取得文字宽度,已设置按钮的contentEdgeInserts
CGFloat width = _tipsButton.intrinsicContentSize.width;
// 此处要用设置的高度20,而不能取内容高度
CGFloat height = 20;
// 左边不规则图形宽度
CGFloat flex = 12;
// 将效果拆分,一个是矩形圆角,一个是不规则色块
UIBezierPath *path1 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(flex, 0, width-flex, height) byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomRight cornerRadii:CGSizeMake(4, 4)];
CAShapeLayer *tipsLayer = [CAShapeLayer layer];
tipsLayer.path = path1.CGPath;
tipsLayer.fillColor = UIColorFromRGB(0xFFEEE8).CGColor;
[_tipsButton.layer insertSublayer:tipsLayer atIndex:0];
第二步,不规则图形,使用了二阶贝塞尔曲线
// 不规则图形
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(0, height)];
// 如果不想调试效果,直接使用这句,画1/4个圆
// [path2 addArcWithCenter:CGPointMake(0, 6) radius:14 startAngle:M_PI_2 endAngle:0 clockwise:NO];
// 这是不断调试效果后的结果,画一个二阶贝塞尔曲线
[path2 addQuadCurveToPoint:CGPointMake(flex, 6) controlPoint:CGPointMake(flex, height)];
[path2 addLineToPoint:CGPointMake(flex, height)];
[path2 closePath];
CAShapeLayer *tipsLayer2 = [CAShapeLayer layer];
tipsLayer2.path = path2.CGPath;
tipsLayer2.fillColor = UIColorFromRGB(0xFFEEE8).CGColor;
[_tipsButton.layer insertSublayer:tipsLayer2 atIndex:0];
最后效果图
后面偶然发现,UIBezierPath可以将2个path叠加,优化后的代码
// 根据内容取得文字宽度,已设置按钮的contentEdgeInserts
CGFloat width = _tipsButton.intrinsicContentSize.width;
// 此处要用设置的高度20,而不能取内容高度
CGFloat height = 20;
// 左边不规则图形宽度
CGFloat flex = 12;
// 将效果拆分,一个是矩形圆角,一个是不规则色块
UIBezierPath *path1 = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(flex, 0, width-flex, height) byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomRight cornerRadii:CGSizeMake(4, 4)];
// 不规则图形
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(0, height)];
// 如果不想调试效果,直接使用这句,画1/4个圆
// [path2 addArcWithCenter:CGPointMake(0, 6) radius:14 startAngle:M_PI_2 endAngle:0 clockwise:NO];
// 这是不断调试效果后的结果,画一个二阶贝塞尔曲线
[path2 addQuadCurveToPoint:CGPointMake(flex, 6) controlPoint:CGPointMake(flex, height)];
[path2 addLineToPoint:CGPointMake(flex, height)];
[path2 closePath];
// 两个path叠加
[path1 appendPath:path2];
CAShapeLayer *tipsLayer = [CAShapeLayer layer];
tipsLayer.path = path1.CGPath;
tipsLayer.fillColor = UIColorFromRGB(0xFFEEE8).CGColor;
[_tipsButton.layer insertSublayer:tipsLayer atIndex:0];