I have an UIView
where I try to draw a signature.
The functionality works but the issue is that my drawing start from 5 centimetres below my cursor and I don't know why.
Here is a gif with my bug:
Here is my small project:DrawSignature
Here is my code for drawing:
struct Line {
let strokeWidth: Float
let color: UIColor
var points: [CGPoint]
}
class Canvas: UIView {
// public function
fileprivate var strokeColor = UIColor.black
fileprivate var strokeWidth: Float = 1
func setStrokeWidth(width: Float) {
self.strokeWidth = width
}
func setStrokeColor(color: UIColor) {
self.strokeColor = color
}
func undo() {
_ = lines.popLast()
setNeedsDisplay()
}
func clear() {
lines.removeAll()
setNeedsDisplay()
}
fileprivate var lines = [Line]()
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
lines.forEach { (line) in
context.setStrokeColor(line.color.cgColor)
context.setLineWidth(CGFloat(line.strokeWidth))
context.setLineCap(.round)
for (i, p) in line.points.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(Line.init(strokeWidth: strokeWidth, color: strokeColor, points: []))
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let point = touches.first?.location(in: nil) else { return }
guard var lastLine = lines.popLast() else { return }
lastLine.points.append(point)
lines.append(lastLine)
setNeedsDisplay()
}
}
And here is my ViewController:
class ViewController: UIViewController {
// Interface Links
@IBOutlet weak var signatureView: Canvas!
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
signatureView.setStrokeColor(color: .black)
}
func setupViews(){
signatureView.layer.borderWidth = 0.5
signatureView.layer.borderColor = UIColor.black.cgColor
signatureView.layer.cornerRadius = 10
}
@IBAction func clearBtnTapped(_ sender: UIButton) {
signatureView.clear()
}
}
I fix it. Problem was at this line:
guard let point = touches.first?.location(in: nil) else { return }
Fix was:
guard let point = touches.first?.location(in: self) else { return }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With