【问题标题】:UIBezierpaths Are Not Drawing Where They Were DrawnUIBezierpath 没有在绘制它们的地方绘制
【发布时间】:2018-09-24 10:46:48
【问题描述】:

在这个“奇怪”的问题上寻求帮助。

我正在使用 PanGesture 允许用户在 CAShapeLayer 上画一条线。

我会跟踪路径直到它们结束,然后将路径存储在路径数组中,从 CAShapeLayer.path 中清除它们的原始路径

当我将这些路径重绘到 UIImage 上时,路径会在 Y-axis 中移向屏幕顶部。

我附上两张图片:

1) 路径的绘制。 Drawing The Path

2) 重绘路径时弹出的 UIImage。如您所见,我沿着网格线绘制,但是,当创建 UIImage 时,该线位于网格线上方。 The Path Redrawn On UIImage

任何建议表示赞赏。

绘制和渲染的代码如下。

    @objc private func drawLine(_ gestureRecognizer: UIPanGestureRecognizer) {

    let point = gestureRecognizer.location(in: self)
    if point.x < 0 || point.x > self.bounds.width || point.y < 0 || point.y > self.bounds.height {
      return
    }

    switch gestureRecognizer.state {
    case .began:
      currentLine = UIBezierPath()
      currentLine.lineWidth = settings.defaultSpotRadius
      currentLine.lineCapStyle = .round
      currentLine.lineJoinStyle = .round
      currentLine.move(to: point)
      break

    case .changed:
      currentLine.addLine(to: point)
      currentLineDrawLayer.path = currentLine.cgPath
      break

    case .ended:
      self.storage.addLine(clear: fowClearMode, path: currentLine, ofWidth: currentLine.lineWidth)
      currentLineDrawLayer.path = nil
      storedImage = drawPaths()
      break

    default:
      break
    }

  }

  public func drawPaths() -> UIImage? {
    if pathsHidden { return nil }

    let rect = CGRect(origin: .zero, size: self.imageSize)
    UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)

    storedImage.draw(in: rect)

    for (isClear, line, width) in thePaths {
      let blendMode = isClear ? settings.colorClear : settings.colorDark
      line.lineWidth = width
      line.stroke(with: blendMode, alpha: 1.0)
    }

    let image = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return image
  }

2018 年 9 月 25 日星期二

我创建了一个仅包含导入点点滴滴的迷你项目。可以在这里找到...Mini-Project

【问题讨论】:

  • 您用于创建图像上下文的self.imageSize 属性是否与您检测到gestureRecognizer.location(in: self) 的视图边界的大小完全相同?
  • imageSize 是原始图像的确切大小是的。在任何时候都是一样的。我没有进行任何缩放或调整大小。
  • @fly.ing.fox -- 根据您发布的图像,重新绘制的线“向上”和“向右”移动。您可能需要将坐标转换为适当的坐标空间。如果您发布一个最小的“可运行”代码示例,它会更容易提供帮助。见minimal reproducible example
  • @DonMag - 当你提到翻译坐标时 - 因为我使用 let point = gestureRecognizer.location(in: self) 这不能确保当我重绘该点时它应该是正确的空间?
  • @fly.ing.fox - 从理论上讲,是的......但很难从你发布的内容中分辨出来。您的两个图像的大小不相同,并且“网格线”不太匹配。是否有可能您的 imageView 与您的图像大小不同,因此在您没有意识到的情况下进行缩放?

标签: ios uiimage uibezierpath swift4.2


【解决方案1】:

我认为您有办法让一切按预期工作,但是,要解决您最初的“偏移”问题...

ViewController.swift 中,您将imgDisplay: ImageDisplay 的框架设置为self.view.bounds --- 在这种情况下,它将是1024 x 768

然后在ImageDisplay.swift 中创建aPathImage,大小为1024 x 791,并将该图像设置为子图层。

那么……

您正在基于边界为1024 x 768 的视图跟踪平移手势,然后在1024 x 791 的图像上重新绘制这些线,从而导致“移位”。

请注意,如果您将图像尺寸更改为800 x 600,这种变化会非常明显,并且会更容易看出它与尺寸差异的关系。

您可能想要做的是将imgDisplay的框架大小设置为图像的大小。

试试这个看看会发生什么 - 在ImageDisplay.swift

  override init(frame: CGRect) {
    super.init(frame: frame)

    // add this line        
    self.frame = CGRect(origin: .zero, size: aPathImage.sizeCurrent)

    self.contentMode = .center
    ...

现在,您的平移坐标将匹配所包含图像的坐标。

正如我所说,您还有很长的路要走,但希望这对您有所帮助。

【讨论】:

  • 似乎您发现了问题所在,我在某处缺少帧大小,但查看代码太久让我跳过它。现在看来它有效,因此我将把答案奖励给你:)
猜你喜欢
  • 2016-10-09
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 2011-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多