I want to create a custom shape into a UIView
by drawing it myself using a UIBezierPath
object and render it in drawRect:
. So far I managed to create the shape and stroke it so it is drawn on screen exactly how I want it to be. However I can't fill it properly. Here is the code so far:
我想通过使用UIBezierPath对象自己绘制一个自定义形状到UIView中并在drawRect:中呈现出来。到目前为止,我成功地创建了这个形状,并在屏幕上画出了它,这正是我想要的形状。但是我不能把它填满。以下是迄今为止的代码:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.f);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
UIBezierPath *path = [UIBezierPath bezierPath];
[path setLineWidth:2.f];
[path setLineJoinStyle:kCGLineJoinRound];
// Stroke top left arc
//[path moveToPoint:CGPointMake(20.f, 2.f)];
[path addArcWithCenter:CGPointMake(10.f, 10.f) radius:5.f startAngle:3*M_PI/2 endAngle:M_PI clockwise:0];
// Stroke bottom left arc
[path addArcWithCenter:CGPointMake(10.f, 50.f) radius:5.f startAngle:M_PI endAngle:M_PI/2 clockwise:0];
// Stroke bottom line
[path moveToPoint:CGPointMake(10.f, 55.f)];
[path addLineToPoint:CGPointMake(60.f, 55.f)];
// Stroke bottom arc
[path moveToPoint:CGPointMake(80.f, 55.f)];
[path addArcWithCenter:CGPointMake(71.f, 65.f) radius:15.f startAngle:degreesToRadians(315) endAngle:degreesToRadians(215) clockwise:1];
// Stroke bottom right arc
[path moveToPoint:CGPointMake(80.f, 55.f)];
[path addArcWithCenter:CGPointMake(80.f, 50.f) radius:5.f startAngle:M_PI/2 endAngle:0 clockwise:0];
// Stroke top right arc
[path addArcWithCenter:CGPointMake(80.f, 10.f) radius:5.f startAngle:0 endAngle:3*M_PI/2 clockwise:0];
// Close path
[path moveToPoint:CGPointMake(80.f, 5.f)];
[path addLineToPoint:CGPointMake(10.f, 5.f)];
[path stroke];
[path fill];
}
Stroke works as expected, but the fill only fills portions on the path
, instead of filling the entire path
. Is there something I'm missing?
描边按预期工作,但是填充只填充路径上的部分,而不是填充整个路径。我是不是漏掉了什么?
Thanks in advance!
提前谢谢!
3 个解决方案
#1
3
Remove all your
删除你所有的
- (void)moveToPoint:(CGPoint)point
methods except the first one because it is a continuous path you don't need it.
方法,除了第一个因为它是一个连续路径你不需要它。
It is highly recommended to close the path by calling the method - (void)closePath
because you are having 3 pixel gap.
强烈建议通过调用method - (void)close path关闭路径,因为您有3个像素间隔。
#2
2
I figured it out. Just needed to get rid of moveToPoint: calls since they create subpaths and so the filling will only affect the new subpaths. And finally called closePath.
我想出来。只需删除moveToPoint:调用,因为它们创建子路径,因此填充只会影响新的子路径。最后叫closePath。
Now my path is continuous and the fill works for the entire shape.
现在我的路径是连续的,整个形状的填充工作。
Edited code:
编辑代码:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
UIBezierPath *path = [UIBezierPath bezierPath];
[path setLineWidth:2.f];
[path setLineJoinStyle:kCGLineJoinRound];
// Stroke top left arc
[path addArcWithCenter:CGPointMake(10.f, 10.f) radius:5.f startAngle:3*M_PI/2 endAngle:M_PI clockwise:0];
// Stroke bottom left arc
[path addArcWithCenter:CGPointMake(10.f, 50.f) radius:5.f startAngle:M_PI endAngle:M_PI/2 clockwise:0];
// Stroke bottom arc
[path addArcWithCenter:CGPointMake(71.f, 65.f) radius:15.f startAngle:degreesToRadians(215) endAngle:degreesToRadians(315) clockwise:0];
// Stroke bottom right arc
[path addArcWithCenter:CGPointMake(80.f, 50.f) radius:5.f startAngle:M_PI/2 endAngle:0 clockwise:0];
// Stroke top right arc
[path addArcWithCenter:CGPointMake(80.f, 10.f) radius:5.f startAngle:0 endAngle:3*M_PI/2 clockwise:0];
// Close path
[path closePath];
[path fill];
[path stroke];
}
}
#3
0
Simply call the method
简单地调用该方法
- (void)closePath
at the end to close your UIBezierPath.
最后关闭UIBezierPath。
#1
3
Remove all your
删除你所有的
- (void)moveToPoint:(CGPoint)point
methods except the first one because it is a continuous path you don't need it.
方法,除了第一个因为它是一个连续路径你不需要它。
It is highly recommended to close the path by calling the method - (void)closePath
because you are having 3 pixel gap.
强烈建议通过调用method - (void)close path关闭路径,因为您有3个像素间隔。
#2
2
I figured it out. Just needed to get rid of moveToPoint: calls since they create subpaths and so the filling will only affect the new subpaths. And finally called closePath.
我想出来。只需删除moveToPoint:调用,因为它们创建子路径,因此填充只会影响新的子路径。最后叫closePath。
Now my path is continuous and the fill works for the entire shape.
现在我的路径是连续的,整个形状的填充工作。
Edited code:
编辑代码:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
UIBezierPath *path = [UIBezierPath bezierPath];
[path setLineWidth:2.f];
[path setLineJoinStyle:kCGLineJoinRound];
// Stroke top left arc
[path addArcWithCenter:CGPointMake(10.f, 10.f) radius:5.f startAngle:3*M_PI/2 endAngle:M_PI clockwise:0];
// Stroke bottom left arc
[path addArcWithCenter:CGPointMake(10.f, 50.f) radius:5.f startAngle:M_PI endAngle:M_PI/2 clockwise:0];
// Stroke bottom arc
[path addArcWithCenter:CGPointMake(71.f, 65.f) radius:15.f startAngle:degreesToRadians(215) endAngle:degreesToRadians(315) clockwise:0];
// Stroke bottom right arc
[path addArcWithCenter:CGPointMake(80.f, 50.f) radius:5.f startAngle:M_PI/2 endAngle:0 clockwise:0];
// Stroke top right arc
[path addArcWithCenter:CGPointMake(80.f, 10.f) radius:5.f startAngle:0 endAngle:3*M_PI/2 clockwise:0];
// Close path
[path closePath];
[path fill];
[path stroke];
}
}
#3
0
Simply call the method
简单地调用该方法
- (void)closePath
at the end to close your UIBezierPath.
最后关闭UIBezierPath。