如何清空UIView?

How to clear UIView?

我正在开发一个绘图应用程序,用户可以在该应用程序的视图上绘制内容。在同一个视图控制器上,我想创建一个按钮,该按钮将擦除视图上的所有内容并为其提供空白。我该怎么做?我添加了所有附加到 uiview 的代码来绘制对象。

 import uikit 
class ViewController: UIViewController {
@IBOutlet weak var jj: draw!

@IBAction func enterScore(_ sender: Any) {
    (view as? drawViewSwift)?.clear()

}}

import  UIKit


 struct stroke {
let startPoint: CGPoint
let endPoint:  CGPoint
let color: CGColor

  }
class drawViewSwift: subClassOFUIVIEW {

var isDrawing = false
var lastPoint : CGPoint!
var strokeColor : CGColor = UIColor.black.cgColor
var storkes = [stroke]()
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard !isDrawing else {return}
    isDrawing = true
    guard let touch = touches.first else {return}
    let currentPoint = touch.location(in: self)

    lastPoint = currentPoint
    setNeedsDisplay()
}
 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard isDrawing else {return}
    guard let touch = touches.first else {return}
    setNeedsDisplay()

    let currentPoint = touch.location(in: self)
    print(currentPoint)
    let sstroke = stroke(startPoint: lastPoint, endPoint: currentPoint, color: strokeColor)
    storkes.append(sstroke)

    lastPoint = currentPoint

}
 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard isDrawing else {return}
    isDrawing = false
    guard let touch = touches.first else {return}
    let currentPoint = touch.location(in: self)
    let sstroke = stroke(startPoint: lastPoint, endPoint: currentPoint, color: strokeColor)
    storkes.append(sstroke)
    lastPoint = nil
    setNeedsDisplay()
    print(currentPoint)
}

private var clearing = false



func clear() {
    clearing = true
    setNeedsDisplay()
}

override func draw(_ rect: CGRect) {
    super.draw(rect)

    defer { setNeedsDisplay() }
    let context = UIGraphicsGetCurrentContext()

    guard !clearing else {
        context?.clear(bounds)
        context?.setFillColor(backgroundColor?.cgColor ?? UIColor.clear.cgColor)
        context?.fill(bounds)
        storkes.removeAll()
        clearing = false
        return
    }
    context?.setLineWidth(10)
    context?.setLineCap(.round)
    for stroke in storkes {
        context?.beginPath()
        context?.move(to:stroke.startPoint)
        context?.addLine(to: stroke.endPoint)
        context?.setStrokeColor(stroke.color)
        context?.strokePath()
    }
}

func crase() {
    storkes = []
    strokeColor = UIColor.black.cgColor
    setNeedsDisplay()
}
  }
  class subClassOFUIVIEW: UIView {

override func awakeFromNib() {

    layer.shadowOpacity = 1
    layer.shadowOffset = CGSize(width: 1, height: 1)
    layer.shadowPath = CGPath(rect: bounds, transform: nil)
    layer.shadowPath = CGPath(rect: bounds, transform: nil)
}
  }

  class MyViewController : UIViewController {
override func loadView() {
    let view = drawViewSwift()
    view.backgroundColor = .white

    let button = UIButton()
    button.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
    button.setTitle("Clear", for: .normal)
    button.setTitleColor(.blue, for: .normal)
    button.addTarget(self, action: #selector(clear), for: .touchUpInside)
    view.addSubview(button)
    self.view = view
}

@objc func clear() {
    (view as? drawViewSwift)?.clear()
}
   }

如果罢工次数较多 - 推荐

如果你的笔画数组太大。我建议使用下面的代码

let rectangle = CGRect(x: 0, y: 0, width: self.height, height: self.height)

CGContextSetFillColorWithColor(context, UIColor.white.CGColor)
CGContextAddRect(context, rectangle)
CGContextDrawPath(context, .Fill)

如果用户没有抽中很多次

因为所有当前绘制的笔画都在数组笔画中。下面的方法也可以。

只需用您的视图背景颜色重新绘制上面的笔触

override func clearView() {
    let context = UIGraphicsGetCurrentContext()
    context?.setLineWidth(10)
    context?.setLineCap(.round)
    for stroke in storkes {
    context?.beginPath()
    context?.move(to:stroke.startPoint)
    context?.addLine(to: stroke.endPoint)
    context?.setStrokeColor(UIColor.white.cgColor)
          // Assuming your background color is white
    context?.strokePath()
    }   

}

您可以将此代码添加到您的 drawViewSwift class:

private var clearing = false
func clear() {
  clearing = true       
  setNeedsDisplay()
}

此时你的 drawRect 应该改变以清除视图:

override func draw(_ rect: CGRect) {
  super.draw(rect)

  defer { setNeedsDisplay() }
  let context = UIGraphicsGetCurrentContext()

  guard !clearing else {
    context?.clear(bounds)
    context?.setFillColor(backgroundColor?.cgColor ?? UIColor.clear.cgColor)
    context?.fill(bounds)
    storkes.removeAll()
    clearing = false
    return
  }
  context?.setLineWidth(10)
  context?.setLineCap(.round)
  for stroke in storkes {
    context?.beginPath()
    context?.move(to:stroke.startPoint)
    context?.addLine(to: stroke.endPoint)
    context?.setStrokeColor(stroke.color)
    context?.strokePath()
  }
}

在守卫中,我们将调用上下文的职员方法,该方法会将上下文重置为初始状态。此方法将导致上下文重绘透明视图。由于视图现在是透明的,我们必须重新绘制 canvas 以再次使用背景色。我们在将填充颜色设置为视图的背景颜色后,使用 fill 方法来实现。

此时剩下要做的就是清除我们的笔画数组并将清除的值切换回 false,以便我们准备好再次绘制。

在您的视图控制器中,清除按钮只需调用该视图的清除方法即可。

在操场上试试:

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

struct stroke {
  let startPoint: CGPoint
  let endPoint:  CGPoint
  let color: CGColor

}
class drawViewSwift: subClassOFUIVIEW {

  var isDrawing = false
  var lastPoint : CGPoint!
  var strokeColor : CGColor = UIColor.black.cgColor
  var storkes = [stroke]()
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard !isDrawing else {return}
    isDrawing = true
    guard let touch = touches.first else {return}
    let currentPoint = touch.location(in: self)

    lastPoint = currentPoint
    setNeedsDisplay()
  }
  override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard isDrawing else {return}
    guard let touch = touches.first else {return}
    setNeedsDisplay()

    let currentPoint = touch.location(in: self)
    print(currentPoint)
    let sstroke = stroke(startPoint: lastPoint, endPoint: currentPoint, color: strokeColor)
    storkes.append(sstroke)

    lastPoint = currentPoint

  }
  override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard isDrawing else {return}
    isDrawing = false
    guard let touch = touches.first else {return}
    let currentPoint = touch.location(in: self)
    let sstroke = stroke(startPoint: lastPoint, endPoint: currentPoint, color: strokeColor)
    storkes.append(sstroke)
    lastPoint = nil
    setNeedsDisplay()
    print(currentPoint)
  }

  private var clearing = false
  func clear() {
    clearing = true
    setNeedsDisplay()
  }

  override func draw(_ rect: CGRect) {
    super.draw(rect)

    defer { setNeedsDisplay() }
    let context = UIGraphicsGetCurrentContext()

    guard !clearing else {
      context?.clear(bounds)
      context?.setFillColor(backgroundColor?.cgColor ?? UIColor.clear.cgColor)
      context?.fill(bounds)
      storkes.removeAll()
      clearing = false
      return
    }
    context?.setLineWidth(10)
    context?.setLineCap(.round)
    for stroke in storkes {
      context?.beginPath()
      context?.move(to:stroke.startPoint)
      context?.addLine(to: stroke.endPoint)
      context?.setStrokeColor(stroke.color)
      context?.strokePath()
    }
  }

  func crase() {
    storkes = []
    strokeColor = UIColor.black.cgColor
    setNeedsDisplay()
  }
}
class subClassOFUIVIEW: UIView {

  override func awakeFromNib() {

    layer.shadowOpacity = 1
    layer.shadowOffset = CGSize(width: 1, height: 1)
    layer.shadowPath = CGPath(rect: bounds, transform: nil)
    layer.shadowPath = CGPath(rect: bounds, transform: nil)
  }
}

class MyViewController : UIViewController {
  override func loadView() {
    let view = drawViewSwift()
    view.backgroundColor = .white

    let button = UIButton()
    button.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
    button.setTitle("Clear", for: .normal)
    button.setTitleColor(.blue, for: .normal)
    button.addTarget(self, action: #selector(clear), for: .touchUpInside)
    view.addSubview(button)
    self.view = view
  }

  @objc func clear() {
    (view as? drawViewSwift)?.clear()
  }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

您绘制和清除作品的代码。您应该更正您的 viewController 代码和您选择的布局结构。我认为最好制作一个专门用于绘制的视图,例如,您可以在主视图中放置 3 个不同的对象,一个用于标签,另一个用于按钮,最后一个用作 drawViewSwift。使用这种结构,您的主视图可以处理对象之间的约束,而其他对象不会干扰绘图(显然是清洁..):

布局:

输出: