我正在绘制条形图,并且我有几个堆叠的CGRect直接相互叠加(即一个rect的minY是前一个rect的maxY).但是,这些地方之间仍然存在半透明的差距.有没有什么办法解决这一问题?我发现在绘制接触相邻弧时也会发生这种情况.
这是我的意思截图:
通过放大,我已经确认这不仅仅是在相邻的红色和蓝色之间发现的视错觉.我很感激任何意见.
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)
)
}
}
Run Code Online (Sandbox Code Playgroud)
忽略关于条的宽度的东西.这是translateY函数.基本上,它将坐标从绘图窗口转换为绘制的x/y内容.请记住,因为窗口/绘图区域在绘制的rects之间不会改变,所以相同的y输入将始终产生相同的结果.
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)
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
这是我的代码的简化版本,显示了问题:
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)
}
Run Code Online (Sandbox Code Playgroud)
它产生了这个:
我怀疑在这种特殊情况下,你填充的rects不是整数,即它们可能具有默认情况下使用略微透明的像素(抗锯齿)渲染的原点/高度.您可以通过正确舍入Y轴平移来避免这种情况
private func translateY(y: CGFloat) -> CGFloat {
if barsAreReversed {
return round(graphingArea.minY + graphingArea.height * (y - graphingWindow.startValue) / (graphingWindow.length))
} else {
return round(graphingArea.maxY - graphingArea.height * (y - graphingWindow.startValue) / (graphingWindow.length))
}
}
Run Code Online (Sandbox Code Playgroud)
使用弧形和其他形状并不容易,但是,您可以通过在形状之间留下一些重叠来尝试摆脱它.当然,正如matt指出的那样,你可以简单地关闭抗锯齿,在这种情况下,这些透明的"半像素"将被渲染,好像它们实际上完全在矩形内.