swiftxcode10forced-unwrapping

fixing - Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value


I am new to coding and have been trying to make an area on the screen that I can sign with my finger. I have made the box but I am struggling to clear it. I have made a button connected to a function to clear the path but I can't seem to work out how to safely unwrap the information without it crashing.

import UIKit

class canvasView: UIView {

    var lineColour:UIColor!
    var lineWidth:CGFloat!
    var path:UIBezierPath!
    var touchPoint:CGPoint!
    var startingPoint:CGPoint!


    override func layoutSubviews() {
        self.clipsToBounds = true
        self.isMultipleTouchEnabled = false

        lineColour = UIColor.white
        lineWidth = 10
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        startingPoint = (touch?.location(in: self))!
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        touchPoint = touch?.location(in: self)

        path = UIBezierPath()
        path.move(to: startingPoint)
        path.addLine(to: touchPoint)
        startingPoint = touchPoint

        drawShapelayer()
    }
    func drawShapelayer(){
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.strokeColor = lineColour.cgColor
        shapeLayer.lineWidth = lineWidth
        shapeLayer.fillColor = UIColor.clear.cgColor
        self.layer.addSublayer(shapeLayer)
        self.setNeedsDisplay()
    }

    func clearCanvas() {
        path.removeAllPoints()
        self.layer.sublayers = nil
        self.setNeedsDisplay()
    }

I then get the error in my final function after

path.removeAllPoints()

How is best to unwrap it to stop it crashing?

Thank you for your patience


Solution

  • The problem is that if the user clicks the button to clear the canvas before he/she draws anything, then the error will occur, since path is only assigned a value in touchesMoved().

    You might want to change

    var path:UIBezierPath!
    

    to

    var path:UIBezierPath?
    

    Though this may seem tedious since you have to add question marks everywhere you try to access a method or property of path, it's much safer, and the code in your example will not crash.

    P.S. Check out this answer. It provides a lot of information regarding the use of optionals.