如何使用quartz2d/coregraphics绘制圆角三角形
Posted
技术标签:
【中文标题】如何使用quartz2d/coregraphics绘制圆角三角形【英文标题】:How to draw a triangle with rounded corners using quartz2d/coregraphics 【发布时间】:2012-11-24 04:27:01 【问题描述】:好吧,所以我想像这样画一个三角形:
目前我正在使用 CAShapeLayer 的组合并使用 UIBezierPath 创建路径(代码如下),然后将其用作另一层的掩码(self.layer,因为我在 UIView 子类中,而不是而不是设置 layerclass 我这样做是为了保留初始层)
反正代码:
_bezierPath = [[UIBezierPath bezierPath] retain];
#define COS30 0.86602540378
#define SIN30 0.5
[_bezierPath moveToPoint:(CGPoint)self.frame.size.width/2.f-r*SIN30,r*COS30];
[_bezierPath addArcWithCenter:(CGPoint)self.frame.size.width/2.f,r*COS30*2.f radius:r startAngle:2*M_PI/3.f endAngle:M_PI/3.f clockwise:YES];
[_bezierPath addLineToPoint:(CGPoint)self.frame.size.width-r*SIN30,self.frame.size.height-r*COS30];
[_bezierPath addArcWithCenter:(CGPoint)self.frame.size.width-r*SIN30-r,self.frame.size.height-r*COS30 radius:r startAngle:0.f endAngle:-M_PI/3.f clockwise:YES];
[_bezierPath addLineToPoint:(CGPoint)r*SIN30,self.frame.size.height-r*COS30];
[_bezierPath addArcWithCenter:(CGPoint)r*SIN30+r,self.frame.size.height-r*COS30 radius:r startAngle:4*M_PI/3.f endAngle:M_PI clockwise:YES];
[_bezierPath closePath];
CAShapeLayer *s = [CAShapeLayer layer];
s.frame = self.bounds;
s.path = _bezierPath.CGPath;
self.layer.mask = s;
self.layer.backgroundColor = [SLInsetButton backgroundColorForVariant:SLInsetButtonColorForSLGamePieceColor(_color)].CGColor;
不幸的是结果不是我想要的,而是角落变成了小旋钮(好像它转动太多了)
提前致谢
【问题讨论】:
为什么是 cos (30) 而不是 60? 你指的是哪种情况? 【参考方案1】:一位才华横溢的朋友(John Heaton,如果你遇到他,他非常棒)让我想起了核心图形部署的 lineCap 和 lineJoin 属性。
某处:
#define border (10.f)
在你的界面中:
@property (nonatomic, strong) UIBezierPath *bezierPath;
在你的初始化中,创建一个像这样的短路径:
CGFloat inset = border / 2.f;
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:(CGPoint) self.frame.size.width/2.f, inset ];
[bezierPath addLineToPoint:(CGPoint) self.frame.size.width - inset, self.frame.size.height - inset ];
[bezierPath addLineToPoint:(CGPoint) a, self.frame.size.height - a ];
[bezierPath closePath];
self.bezierPath = bezierPath;
然后在您的 drawRect:
方法中执行以下操作:
CGContextRef c = UIGraphicsGetCurrentContext(), context = c;
CGColorRef col = [UIColor redColor].CGColor;
CGColorRef bcol = [UIColor redColor].CGColor;
CGContextSetFillColorWithColor(c, col);
CGContextSetStrokeColorWithColor(c, bcol);
CGContextSetLineWidth(c, border);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetLineCap(c, kCGLineCapRound);
CGContextAddPath(c, self.bezierPath.CGPath);
CGContextStrokePath(c);
CGContextAddPath(c, self.bezierPath.CGPath);
CGContextFillPath(c);
这将正确地为您提供三角形上的圆角,还可以选择具有边框或轮廓
【讨论】:
考虑用const
替换#define
!
我选择使用宏而不是像static const
这样的宏,因为你不需要用指针来引用数字,这里不需要额外的类型检查(它在一个假设它是一个浮点数的例程)并且它打开了在编译时使用cli args或在xcode的配置中提供这个常量的能力(ofc名称border
不是最好的,应该改变,但这段代码应该'不是简单的复制/粘贴,应该通读和思考)。
我明白了,但是如果宏改了是不是整个项目都重新编译了?
老实说,我不确定它是重新编译整个项目还是只重新编译必要的文件 - 确保只重新编译该文件的一种方法是仅更改该文件上的标志。无论如何,从我的角度来看,它是一个或六个另一个中的 6 个 - 在我使用它的情况下,使用宏似乎没有好处或坏处,而不是 static const
以上是关于如何使用quartz2d/coregraphics绘制圆角三角形的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]