I'm drawing bar graphs, and I have several stacked CGRects that are directly on top of each other (i.e. one rect's minY is the previous rect's maxY). However, there are still semi-transparent gaps between the rects. Is there any way to fix this? I've found that this also happens when drawing touching adjacent arcs.
Here's a screenshot of what I mean:
By zooming in, I've confirmed that this isn't just an optical illusion like one would find between adjacent red and blue rects. I would appreciate any input.
var upToNowSegmentTotal: CGFloat = 0
for k in 0..<data[i].bars[j].segments.count {
var segmentRect: CGRect = CGRect()
if barDirection == "vertical" {
let a: CGFloat = translateY(upToNowSegmentTotal)
let b: CGFloat = translateY(upToNowSegmentTotal + data[i].bars[j].segments[k].length)
upToNowSegmentTotal += data[i].bars[j].segments[k].length
var rectY: CGFloat
if a > b {
rectY = b
} else {
rectY = a
}
segmentRect = CGRect(
x: barWidthPosition,
y: rectY,
width: barWidthAbsolute,
height: abs(a - b)
)
}
}
Ignore the stuff about the width of the bars. Here's the translateY function. Basically, it translates coordinates from the graphing window into x/y stuff that's drawn. Remember that because the window/ graphing area does not change between drawn rects, the same y input will always produce the same result.
private func translateY(y: CGFloat) -> CGFloat {
if barsAreReversed {
return graphingArea.minY + graphingArea.height * (y - graphingWindow.startValue) / (graphingWindow.length)
} else {
return graphingArea.maxY - graphingArea.height * (y - graphingWindow.startValue) / (graphingWindow.length)
}
}
EDIT 2:
Here's a simplified version of my code that shows the problem:
override func drawRect(rect: CGRect) {
let rect1: CGRect = CGRect(
x: 0,
y: 0,
width: 40,
height: 33.7
)
let rect2: CGRect = CGRect(
x: 0,
y: rect1.height,
width: 40,
height: 33.5
)
let context: CGContextRef = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, UIColor(red: 1 / 255, green: 29 / 255, blue: 29 / 255, alpha: 1).CGColor)
CGContextAddRect(context, rect1)
CGContextFillRect(context, rect1)
CGContextSetFillColorWithColor(context, UIColor(red: 9 / 255, green: 47 / 255, blue: 46 / 255, alpha: 1).CGColor)
CGContextAddRect(context, rect2)
CGContextFillRect(context, rect2)
}
It produces this:
答案 0 :(得分:5)
我怀疑在这种特殊情况下,你填充的部分不是完整的,即它们可能具有默认情况下使用略微透明的像素(抗锯齿)渲染的原点/高度。您可以通过正确舍入Y轴平移来避免这种情况
2> /dev/null
使用弧形和其他形状并不容易,但是,您可以尝试通过在形状之间留下一些重叠来摆脱它。当然,正如亚光所指出的,你可以简单地关闭抗锯齿,在这种情况下,这些透明的半像素&#34;将全部呈现为好像它们实际上完全在矩形内。
答案 1 :(得分:2)
它的抗锯齿。我可以通过使用完全相同的代码但在我们首先调用CGContextSetAllowsAntialiasing(context, false)
的CGContext中绘制来防止这种现象。这是没有的调用:
此处与调用:
但是,正如其他人所说,我们可以通过将33.7和33.5更改为40来获得相同的结果,这样我们就可以在像素边界上进行调整。
答案 2 :(得分:2)
这很可能发生,因为您用于绘制形状的矩形坐标是小数值。因此,当您的坐标落在像素边界之间时,Core Graphics会在这些矩形的边缘执行抗锯齿。
您可以通过在绘制之前简单地舍入矩形的坐标来解决此问题。您可以使用执行此类舍入的CGRectIntegral
函数,例如:
CGContextFillRect(context, CGRectIntegral(rect1))