【问题标题】:SetNeedsDisplay having no effectSetNeedsDisplay 无效
【发布时间】:2019-12-22 09:05:04
【问题描述】:

我正在 UIContainerView 中创建一个子视图,该子视图属于下面描述的类。这些值正确打印到终端窗口,但并未实际显示在我定义的子视图中。我认为 setNeedsDisplay() 应该解决这个问题,但什么都没有出现。

我将此子视图创建为let canvas = Canvas() 并尝试过

canvas.setNeedsDisplay() 无效。

class Canvas: UIView {

  override func draw(_ rect: CGRect) {

      super.draw(rect)
      guard let context = UIGraphicsGetCurrentContext() else { return }

      context.setStrokeColor(login_theme_color.cgColor)
      context.setLineWidth(10.0)
      context.setLineCap(.butt)

      lines.forEach { (line) in
      for(i, p) in line.enumerated(){
          //context.move(to: p)
          //context.addLine(to: p)
          if i == 0 {
              context.move(to: p)
              print("First point of new line is \(p)")
          }else{
              context.addLine(to: p)
              print("point is \(p)")
          }
      }
  }
       context.strokePath()
}

  var lines = [[CGPoint]]()

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
      lines.append([CGPoint]())
      //setNeedsDisplay()
  }
  override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
      guard let point = touches.first?.location(in: nil) else { return }
      guard var lastLine = lines.popLast() else { return }
      lastLine.append(point)
      lines.append(lastLine)
      setNeedsDisplay()
  }

}

为什么值会正确打印到终端,但行数组实际上并未在视图中显示值?非常感谢您的帮助。

我使用以下约束定义我的画布:

    let canvas = Canvas()

    @objc fileprivate func setupCanvas(){
        //canvas.setNeedsDisplay()
        containerView.addSubview(canvas)
        canvas.translatesAutoresizingMaskIntoConstraints = false
        canvas.topAnchor.constraint(equalTo: rectangle2.topAnchor, constant: 74).isActive = true
        canvas.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: (view.frame.width/2) + 8).isActive = true
        canvas.rightAnchor.constraint(equalTo: rectangle2.rightAnchor, constant: -4).isActive = true
        canvas.bottomAnchor.constraint(equalTo: howitWorksText.bottomAnchor, constant: 0).isActive = true
        canvas.layer.cornerRadius = 30
        canvas.layer.shadowRadius = 0.5
        canvas.layer.shadowColor = UIColor.white.cgColor
        //canvas.backgroundColor = UIColor.clear
        //canvas.layer.borderWidth = 2.0
        //canvas.layer.borderColor = UIColor.black.cgColor
        canvas.layer.masksToBounds = true
        canvas.backgroundColor = .white
        //canvas.setNeedsDisplay()
    }

并在我的ViewDidLoad() 中致电setupCanvas()

【问题讨论】:

  • 您是否给您的Canvas 提供了frame 或者您是否有确定其大小的限制条件?如果没有,那么您的 Canvas 视图具有 0 宽度和 0 高度,因此它不可见。
  • 我有限制,这个视图按预期显示。
  • touchesMoved 中尝试guard let point = touches.first?.location(in: self) else { return }
  • 我想知道该点的位置是否在您的窗口之外。尝试使用 location(in: self) 而不是 location(in: nil) 看看你会得到什么
  • 这成功了!非常感谢!

标签: swift uiview uicontainerview setneedsdisplay


【解决方案1】:

您的坐标已关闭,因为您使用了错误的参考系。为location(in view:) 中的视图指定nil 会选择窗口 的坐标空间。因此,即使您的触摸在画布内,您的绘图也不在。您想通过将 self 而不是 nil 传递给 location(in:) 来获取 Canvas 视图内的触摸坐标。

touchesMoved() 更改:

guard let point = touches.first?.location(in: nil) else { return }

到:

guard let point = touches.first?.location(in: self) else { return }

有关更多信息,请查看location(in:) 的文档。

【讨论】:

  • 补充一点——从nil转换与从窗口坐标转换是一样的。
  • 谢谢@rmaddy,我在答案中添加了这些信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多