问题
My code uses to classes. When the function dizzy is called it changes the color of all the lines in the uiview. What I want it to do is only change lines colors that are drawn after the function is called. It should not change the color of the lines that are already drawn like it does now.
class ViewController: UIViewController {
@objc func dizzy() {
canvas.strokeColor = .gray
}
var canvas = Canvas()
}
class Canvas: UIView {
var strokeColor = UIColor.green {
didSet {
self.setNeedsDisplay()
}
}
func undo() {
_ = lines.popLast()
setNeedsDisplay()
}
func clear() {
lines.removeAll()
setNeedsDisplay()
}
var lines = [[CGPoint]]()
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
context.setStrokeColor(strokeColor.cgColor)
context.setLineWidth(5)
context.setLineCap(.butt)
lines.forEach { (line) in
for (i, p) in line.enumerated() {
if i == 0 {
context.move(to: p)
} else {
context.addLine(to: p)
}
}
}
context.strokePath()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
lines.append([CGPoint]())
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let point = touches.first?.location(in: self) else { return }
guard var lastLine = lines.popLast() else { return }
lastLine.append(point)
lines.append(lastLine)
setNeedsDisplay()
}
}
回答1:
You need to create a struct
to store the color with the line. In touchesBegan()
, store the current strokeColor
with the coloredLine
. In draw(rect:)
, for every line set the context.setStrokeColor(line.color.cgColor)
before stroking the line.
I tested this by adding buttons to change the colors. You can hook it up as you see fit.
struct ColoredLine {
var color = UIColor.black
var points = [CGPoint]()
}
class ViewController: UIViewController {
@IBOutlet weak var canvas: Canvas!
@IBAction func doRed(_ sender: UIButton) {
canvas.strokeColor = .red
}
@IBAction func doGreen(_ sender: UIButton) {
canvas.strokeColor = .green
}
@IBAction func doBlue(_ sender: UIButton) {
canvas.strokeColor = .blue
}
@IBAction func doBlack(_ sender: UIButton) {
canvas.strokeColor = .black
}
}
class Canvas: UIView {
var strokeColor = UIColor.green
func undo() {
_ = lines.popLast()
setNeedsDisplay()
}
func clear() {
lines.removeAll()
setNeedsDisplay()
}
var lines = [ColoredLine]()
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
context.setLineWidth(5)
context.setLineCap(.butt)
lines.forEach { (line) in
for (i, p) in line.points.enumerated() {
if i == 0 {
context.move(to: p)
} else {
context.addLine(to: p)
}
}
context.setStrokeColor(line.color.cgColor)
context.strokePath()
context.beginPath()
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
var coloredLine = ColoredLine()
coloredLine.color = strokeColor
lines.append(coloredLine)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let point = touches.first?.location(in: self) else { return }
guard var lastLine = lines.popLast() else { return }
lastLine.points.append(point)
lines.append(lastLine)
setNeedsDisplay()
}
}
来源:https://stackoverflow.com/questions/58584028/color-of-cgpoint-changes-all-lines-and-should-only-change-new-lines