I have a drawing app using Core Graphics. Everything works fine. I'm able to draw. I added an "undo" button to undo the line. It works, but...
Problem: Every time the "undo" button is pressed it removes line by line by line. I'm trying to append array of CGPath to an array which will hold the entire drawing. e.g. If I draw a line from the left edge of the screen to the right edge of the screen, when I pressed the "UNDO", it should remove this 'path'(array of CGPoints). It's currently doing line by line which takes like a million "UNDO" calls to remove that same drawpath.
Probable Solution: I think the best way is to collect an array of CGPoints from touchesBegans through touchesEnded and then append it to an array that holds array of CGPoints.
array<array<CGPoint>> //Using something like this
MainViewController: Calling the "UNDO" Action
//calls the "undo" in UIView class
@IBAction func undoButton(sender: AnyObject) {
var theDrawView = drawView as DrawView
theDrawView.undoLastPath()
}
Custom UIView Class:
var lines: [Line] = []
var lastPoint: CGPoint!
var drawColor = UIColor.redColor()
var allLines = Array<Array<CGPoint>>()//Will store arrays of CGPoint Arrays
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
var touch = touches.first as! UITouch
lastPoint = touch.locationInView(self)
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
var touch = touches.first as! UITouch
var newPoint = touch.locationInView(self)
lines.append(Line(start: lastPoint, end: newPoint, color: drawColor))
lastPoint = newPoint
self.setNeedsDisplay()
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
var touch = touches.first as! UITouch
var newPoint = touch.previousLocationInView(self)
//ERROR: lines are not appending!
allLines.append(lines(start: lastPoint, end: newPoint, color: drawColor))
touchesMoved(touches, withEvent: event)
}
override func drawRect(rect: CGRect) {
var context = UIGraphicsGetCurrentContext()
CGContextBeginPath(context)
CGContextSetLineWidth(context, 10.0)
CGContextSetLineCap(context, kCGLineCapRound)
//Currently this works: Will add the new allLines (Array)
for line in lines {
CGContextMoveToPoint(context, line.start.x, line.start.y)
CGContextAddLineToPoint(context, line.end.x, line.end.y)
//CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0)
CGContextSetStrokeColorWithColor(context, line.color.CGColor)
CGContextStrokePath(context)
}
}
func eraseAll(){
lines.removeAll(keepCapacity: false)
self.setNeedsDisplay()
}
Custom Swift class for my line:
class Line {
var start: CGPoint
var end: CGPoint
var color: UIColor
init(start _start: CGPoint, end _end: CGPoint, color: UIColor) {
start = _start
end = _end
color = _color
}
}
I've tried multiple different ways to append the lines array to allLines array but without success.
How can I append my lines draw to this:
array<array<CGPoint>>
I believe you should make your allLines
be an array of array of Line
:
var allLines = [[Line]]()
Then your touchesEnded
becomes:
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
var touch = touches.first as! UITouch
var newPoint = touch.previousLocationInView(self)
lines.append(Line(start: lastPoint, end: newPoint, color: drawColor))
allLines.append(lines)
// Prep lines to hold the next line
lines = []
}
and in your drawRect
:
for lines in allLines {
for line in lines {
CGContextMoveToPoint(context, line.start.x, line.start.y)
CGContextAddLineToPoint(context, line.end.x, line.end.y)
//CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0)
CGContextSetStrokeColorWithColor(context, line.color.CGColor)
CGContextStrokePath(context)
}
}
and undoLastPath
is simply:
func undoLastPath() {
if count(allLines) > 0 {
allLines.removeLast()
self.setNeedsDisplay()
}
}