我正在使用 Core Graphics 在 iPhone 上制作一个圆角矩形 float 对话框。沿着同心圆角矩形路径应用笔划时,笔划之间的间隙总是出现在拐角处。这些相同的笔划并排位于直线段上。
代码的相关摘录(删除了无关的代码):
-(void)drawRect:(CGRect)rect {
CGRect borderRect = CGRectInset(rect, 1.0, 1.0);
UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:borderRect cornerRadius:6.0];
[...]
CGContextSetStrokeColorWithColor(context, bevelStrokeColor);
CGContextSetLineWidth(context, 2.0);
CGContextAddPath(context, borderPath.CGPath);
CGContextStrokePath(context);
[...]
CGRect inlayRect = CGRectInset(rect, inlayPathInset, inlayPathInset);
UIBezierPath *inlayPath = [UIBezierPath bezierPathWithRoundedRect:inlayRect cornerRadius:6.0];
[...]
CGContextSetStrokeColorWithColor(context, inlayStrokeColor);
CGContextSetLineWidth(context, 2.0);
CGContextAddPath(context, inlayPath.CGPath);
CGContextStrokePath(context);
[...]
}
这是一张图片:
我尝试了上面发布的代码的不同版本。我手动创建了路径,使用 UIBezierPath 实例方法来创建和绘制,并且通过 View 的图层以及各种组合中的其他一些想法设置了cornerRadius。其中一些改善了问题,但并没有消除。
如果我只使用边框,我不会介意,但我也会实现一些同心圆角矩形,这个间隙将是一个问题。
编辑:更正了转录时出现的代码拼写错误。
最佳答案
如果所有笔划的lineWidth都相同,则将innerCornerRadius设置为(outerCornerRadius - lineWidth)似乎可以产生所需的效果;这是一个特例。如果您不相信以下内容,我鼓励您进行测试。真正的关系似乎如下:
li = 内部线宽
lo = 外部线宽
ri = 内角半径
ro = 外角半径
li/2 + ri = ro - lo/2
因此: ri = ro - (li/2 + lo/2)
如果 li = lo = l 则:ri = ro - l
/*
The following should be inserted into a UIView subclass that has a size of ~280, ~200.
lineWidthInner/2 + radiusInner = radiusOuter - lineWidthOuter/2
radiusInner = radiusOuter - (lineWidthOuter + lineWidthInner)/2
That is to say that the inner corner radius is equal to the outer corner radius
minus the average of the lineWidth's.
innerInsetMargin = outerInsetMargin + (lineWidthOuter + lineWidthInner)/2
The amount a line must be inset (insetMargin) is the previous line's insetMargin + the
average of the previous and current lineWidth's. In the case in which the
outermost line's outer edge touches the bound of rect, the insetMargin is equal
to the sum of all previous lineWidth's plus half of the current lineWidth.
Shutting off anti-aliasing is required to prevent alpha-blending of the non-rectilinear
parts of the line with the background. I am not sure how to gracefully sidestep this.
Insights into this would be appreciated.
*/
-(void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, UIColor.blackColor.CGColor);
CGContextFillRect(context, rect);
CGContextSetShouldAntialias(context,NO);
NSArray *colors = [NSArray arrayWithObjects:
(id)UIColor.greenColor.CGColor,
(id)UIColor.lightGrayColor.CGColor,
(id)UIColor.yellowColor.CGColor,
(id)UIColor.blueColor.CGColor,
(id)UIColor.redColor.CGColor, nil];
//Change lineWidth, lineWidthIncrement, or currentCornerRadius as you see fit
CGFloat lineWidthIncrement = 1.0;
CGFloat lineWidth = 10.0;
CGFloat currentCornerRadius = 100.0;
CGFloat insetMargin = lineWidth/2;
do {
CGContextSaveGState(context);
CGContextSetStrokeColorWithColor(context, (CGColorRef)[colors objectAtIndex:(lcv % colors.count)]);
CGContextSetLineWidth(context, lineWidth);
CGContextAddPath(context, [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, insetMargin, insetMargin) cornerRadius:currentCornerRadius].CGPath);
CGContextStrokePath(context);
CGContextRestoreGState(context);
lineWidth += lineWidthIncrement;
currentCornerRadius -= 0.5 * (lineWidth + (lineWidth - lineWidthIncrement));//-0.5*(lwi+lwo)
insetMargin += 0.5 * (lineWidth + (lineWidth - lineWidthIncrement));
} while(currentCornerRadius>0);
}
关于iphone - 核心显卡0x104567911,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9828235/