Swift CoreGraphics UIBezierPath 不会正确填充内部

标签 swift core-graphics uibezierpath topojson

我正在尝试绘制国家并用某种颜色填充内部。我的数据源是 TopoJSON文件,简而言之,它由引用弧形数组以创建形状的形状组成。我将其转换为 paths 数组,然后对其进行迭代以绘制国家/地区。正如您在下面的屏幕截图中看到的,我正在绘制国家(阿富汗)轮廓的正确线条。

Afghanistan Outline

但是,当我尝试使用 path.fill() 时,我最终得到以下结果。请注意黑线是如何正确的,但颜色随意地从外到内。

Afghanistan filled

代码

var mapRegion = MapRegion()
var path = mapRegion.createPath()
var origin: CGPoint = .zero

geometry.paths
    .enumerated()
    .forEach { (geoIndex, shape) in

        shape
            .enumerated()
            .forEach { (shapeIndex, coord) in

                guard let coordPoint = coord.double else { return }
                let values = coordinatesToGraphics(x: coordPoint.x, y: coordPoint.y)
                let point = CGPoint(x: values.x, y: values.y)

                if origin == .zero {
                    origin = point
                }

                // Shape is about to be closed
                if shapeIndex != 0 && path.contains(point) {

                    // Close, save path (2)
                    path.addLine(to: origin)
                    // (3) path.close()
                    mapRegion.savePath()

                    // Add to map, reset process
                    canvas.layer.addSublayer(mapRegion)
                    mapRegions.append(mapRegion)
                    mapRegion = MapRegion()
                    path = mapRegion.createPath()

                 }

                 else {
                     if shapeIndex == 0 {
                         path.move(to: point)
                     } else {
                         path.addLine(to: point)
                     }
                 }



             }

}

我已经尝试过彻底弄乱 usesEvenOddFillRule ( further reading ),但什么都没有改变。我发现上面的评论 (1) 有助于解决不应该绘制边界的问题。 (2) 处的函数 savePath() 运行 setStroke()stroke()setFill() , fill() 函数。

更新:path.close() 在形状的左下角绘制一条闭合路径的线,而不是在它所在的左上角首先开始绘图。该函数关闭了“最近添加的子路径”,但是子路径是如何定义的?

我不能确定问题出在我的逻辑上还是某些 CoreGraphics 技巧上。我有一系列路径需要拼接在一起并视为一个路径,我相信我正在这样做。我查看了数据点,一个弧的结尾到下一个弧的开头是相同的。我打印了拼接在一起的路径,我基本上 move(to:) 相同的点,所以当我 addLine(to:) 时没有重复模拟器正在为区域着色,我首先猜测可能是将各个弧线视为形状,但在这个示例中只有 6 个弧线,还有几个内外颜色切换。

我真的很感激这里的任何帮助!

最佳答案

事实证明,使用 path.move(to:)UIBezierPath() 中创建了一个 subpath,填充算法似乎将其处理作为单独的多条路径(导致发现的 source)。解决方案是删除额外的、不必要的 move(to:) 调用。下面是工作代码和快乐的结果!谢谢!

var mapRegion = MapRegion()
var path = mapRegion.createPath()
path.move(to: .zero)
var pointsDictionary: [String: Bool] = [:]

geometry.paths
  .enumerated()
  .forEach { (geoIndex, shape) in

      shape
          .enumerated()
          .forEach { (shapeIndex, coord) in

              guard let coordPoint = coord.double else { return }
              let values = coordinatesToGraphics(x: coordPoint.x, y: coordPoint.y)
              let point = CGPoint(x: values.x, y: values.y)

              // Move to start
              if path.currentPoint == .zero {
                  path.move(to: point)
              }

              if shapeIndex != 0 {

                  // Close shape
                  if pointsDictionary[point.debugDescription] ?? false {

                      // Close path, set colors, save
                      mapRegion.save(path)
                      regionDrawer.drawPath(of: mapRegion)

                      // Reset process
                      canvas.layer.addSublayer(mapRegion)
                      mapRegions.append(mapRegion)
                      mapRegion = MapRegion()
                      path = mapRegion.createPath()
                      pointsDictionary = [:]

                  }

                  // Add to shape
                  else {
                      path.addLine(to: point)
                  }

              }

      }

}

enter image description here

关于Swift CoreGraphics UIBezierPath 不会正确填充内部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50993255/

相关文章:

ios - UINavigationBar Tint Color 与 IOS 中其余应用程序之间的色差

iphone - 如何使用 UIBezierPath 裁剪图像?

swift - 使用带有 getter 和 setter 的类或结构来计算关系的属性

ios - SWIFT:如何向 NSDate 对象添加小时数

swift - 如何在不中断视频预览的情况下仅在录制时将音频输入添加到 AVCaptureSession?

iphone - 在 UIImageView 上绘画具有更好的性能

ios - 如何在 cocoa 中获得图像的作者

objective-c - 为什么 CGWarpMouseCursorPosition 会导致延迟?如果不是,那是什么?

ios - 根据随机 CGFloat 值重新绘制 UIBezierPath

ios - 在 Swift 中从 Uibezierpath 数组创建一个 UIImage