I followed a raywenderlich tutorial on using the UIKit to make a drawing app. I'm now trying to add in the functionality to undo the last stroke. Ideally I would like to undo up to 10ish strokes. I'm trying to figure out what is the best way to go about doing this. I was thinking of creating another ImageView which has only the last stroke and making the ImageView.image = nil
when the user presses back. In the code from the tutorial there's something similar to this. When the touches end, the newest stroke is merged onto the imageview with all of the old ones at the right opacity. I'm not really sure how I could add this third (and potentially more) imageivews to this code to make it work. Any ideas / a better way to go about this? Code for touchesEnded is below.
Code
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
if !swiped {
// draw a single point
drawLineFrom(lastPoint, toPoint: lastPoint)
}
// Merge tempImageView into mainImageView
UIGraphicsBeginImageContext(mainImageView.frame.size)
mainImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0)
tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: opacity)
mainImageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
tempImageView.image = nil
}
@SpaceShroomies: I found/came up with a great solution..
I used parts from nsHiptser, and from the Raywenderlich tutorial.
And here i my solution:
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
//undoManager
let undo: UIImageView = undoManager?.prepareWithInvocationTarget(Temp2Image) as! UIImageView
UIGraphicsBeginImageContext(Temp2Image.frame.size)
Temp2Image.image?.drawInRect(CGRect(x: 0, y: 0, width: Temp2Image.frame.size.width, height: Temp2Image.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0)
TempImage.image?.drawInRect(CGRect(x: 0, y: 0, width: TempImage.frame.size.width, height: TempImage.frame.size.height), blendMode: kCGBlendModeNormal, alpha: opacity)
undo.image = Temp2Image.image
Temp2Image.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
TempImage.image = nil
}
The important thing here is to set, what UNDO should go back to I.e. undo.image = Temp2Image.image
otherwise it will not change "it" back
So I managed to get an undo function working for one step backwards by having a UIImageView that stores the last stroke before it's added to the rest of the strokes when the next stroke is complete... Would there be something wrong with using the same technique to go backwards 10 steps? I would need 10 UIImageViews... Would that be inefficient / cause crashing? The code is below:
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
if !swiped {
// draw a single point
drawLineFrom(lastPoint, toPoint: lastPoint)
}
UIGraphicsBeginImageContext(mainImageView.frame.size)
mainImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0)
undo1.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0)
mainImageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
undo1.image = nil
UIGraphicsBeginImageContext(undo1.frame.size)
undo1.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0)
tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: opacity)
undo1.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
tempImageView.image = nil
}