Pixel Gap Between CGRect

时间:2015-07-28 16:30:31

标签: ios swift

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:

enter image description here

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:

enter image description here

3 个答案:

答案 0 :(得分:5)

我怀疑在这种特殊情况下,你填充的部分不是完整的,即它们可能具有默认情况下使用略微透明的像素(抗锯齿)渲染的原点/高度。您可以通过正确舍入Y轴平移来避免这种情况

2> /dev/null

使用弧形和其他形状并不容易,但是,您可以尝试通过在形状之间留下一些重叠来摆脱它。当然,正如亚光所指出的,你可以简单地关闭抗锯齿,在这种情况下,这些透明的半像素&#34;将全部呈现为好像它们实际上完全在矩形内。

答案 1 :(得分:2)

它的抗锯齿。我可以通过使用完全相同的代码但在我们首先调用CGContextSetAllowsAntialiasing(context, false)的CGContext中绘制来防止这种现象。这是没有的调用:

enter image description here

此处调用:

enter image description here

但是,正如其他人所说,我们可以通过将33.7和33.5更改为40来获得相同的结果,这样我们就可以在像素边界上进行调整。

答案 2 :(得分:2)

这很可能发生,因为您用于绘制形状的矩形坐标是小数值。因此,当您的坐标落在像素边界之间时,Core Graphics会在这些矩形的边缘执行抗锯齿。

您可以通过在绘制之前简单地舍入矩形的坐标来解决此问题。您可以使用执行此类舍入的CGRectIntegral函数,例如:

CGContextFillRect(context, CGRectIntegral(rect1))