I want my swift code to draw a straight horiziontal line. Right now it selects a point and the user extends the line anchored in the first point. I just want the user to be able to draw the line left or right. I tried alternating bezier.addLine(to: CGPoint(x:startTouch!.x, y:startTouch!.y)) but that does not seem to have any effect.
import UIKit
class ViewController2: UIViewController {
@IBOutlet weak var drawingPlace: UIImageView!
var startTouch : CGPoint?
var secondTouch : CGPoint?
var currentContext : CGContext?
var prevImage : UIImage?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemOrange
drawingPlace.backgroundColor = .gray
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
startTouch = touch?.location(in: drawingPlace)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
secondTouch = touch.location(in: drawingPlace)
if(self.currentContext == nil){
UIGraphicsBeginImageContext(drawingPlace.frame.size)
self.currentContext = UIGraphicsGetCurrentContext()
}else{
self.currentContext?.clear(CGRect(x: 0, y: 0, width: drawingPlace.frame.width, height: drawingPlace.frame.height))
}
self.prevImage?.draw(in: self.drawingPlace.bounds)
let bezier = UIBezierPath()
bezier.move(to: startTouch!)
bezier.addLine(to: secondTouch!)
bezier.addLine(to: CGPoint(x:startTouch!.x, y:startTouch!.y))
bezier.close()
UIColor.blue.set()
self.currentContext?.setLineWidth(4)
self.currentContext?.addPath(bezier.cgPath)
self.currentContext?.strokePath()
let img2 = self.currentContext?.makeImage()
drawingPlace.image = UIImage.init(cgImage: img2!)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.currentContext = nil
self.prevImage = self.drawingPlace.image
}
}
If you want to draw a horizontal line, create a
CGPointwhosexis the location of the touch and whoseyis that of the starting point. That will result in a horizontal line.That having been said, here are a few other of observations:
If you call
UIGraphicsBeginImageContext, you must callUIGraphicsEndImageContext. You should do this withintouchesMoved, not trying to hang on to the context beyond this call.If you were to do this, we would generally use
UIGraphicsImageRenderernowadays.Personally, I wouldn't try rendering an image for every touch. That is a pretty expensive operation. I would just add a
CAShapeLayerand then update thepathfor that layer. LetCAShapeLayertake care of the rendering of the path.I'm not quite sure why you are iterating through the array of touches. I would just grab one and use that.
I might suggest using predictive touches to minimize perceived lagginess.
The
startTouchis actually aCGPoint, not aUITouch, so I might call itstartPointinstead.If you want to make a snapshot image, I'd do that in
touchesEnded, not intouchesMoved.For example:
This just renders the current line as a
CAShapeLayer, but when the stroke is done, it creates a snapshot of the image view (permanently capturing the stroke in an image), removes the shape layer’s path, and updates the image view’simage.But hopefully this answers the question on how to make the line horizontal.