* Update Shortly after posting I found this which looks to have all my answers. Not yet worked it out for myself but this might help anyone else with similar issue. Scratch Card effect in Swift 3 End Update *
This is my first question to Stack so apologies if it's a bit 'noob'. My question kind of has two parts. I've used a couple of tutorials which have shown me how to draw lines over an image in an imageView, but I'm struggling to achieve my goal of revealing an image beneath an overlayer by drawing a "clear" line on the layer. Imagine a scratch card... that is the effect I'm after.
I have used the following Stack question/answer to help guide me initially Draw a line realtime with Swift 3.0; but my end goal is being thwarted further by the confusion of image/view bounds.
The tutorial above works great for initial drawing, except when I touch the screen, the position of my finger is converted to the imageView coordinates, so the line never appears where I place my finger. I would really like someone to help my convert the coords so the line draws exactly where I place my finger. I've tried changing the bounds in the 'Draw line' func, but I get strange behaviour from the image and the drawing stops working completely.
If anyone is able to help on either issue I'd be really grateful. And if I need to split the questions then I will do so. I've attached my code if it helps. Thanks for looking...
class ViewController: UIViewController {
@IBOutlet weak var myImageView: UIImageView!
var layer: CALayer {
return myImageView.layer
}
var lastPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = false
if let touch = touches.first {
lastPoint = touch.location(in: self.view)
}
}
func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)
myImageView.image?.draw(in: view.bounds)
let context = UIGraphicsGetCurrentContext()
context?.move(to: fromPoint)
context?.addLine(to: toPoint)
context?.setLineCap(CGLineCap.round)
context?.setLineWidth(brushWidth)
context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
context?.setBlendMode(CGBlendMode.normal)
context?.strokePath()
myImageView.image = UIGraphicsGetImageFromCurrentImageContext()
myImageView.alpha = opacity
UIGraphicsEndImageContext()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = true
if let touch = touches.first {
let currentPoint = touch.location(in: view)
drawLine(from: lastPoint, to: currentPoint)
lastPoint = currentPoint
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if !swiped {
// draw a single point
self.drawLine(from: lastPoint, to: lastPoint)
}
}
func setUpLayer() {
layer.backgroundColor = UIColor.clear.cgColor
layer.borderWidth = 10.0
layer.borderColor = UIColor.red.cgColor
layer.shadowOpacity = 0.7
layer.shadowRadius = 10.0
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myImageView.image = UIImage(named: "8BitGirls.png")
setUpLayer()
}
}