-2

I had trying do a circular progress bar, but when I run the app, it crashes and show me the next error:

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/marcoalonso/Documents/SWIFT_PROJECTS/CircularProgressView/CircularProgressView/ViewController.swift, line 15 2020-04-18 19:26:48.103695-0500 CircularProgressView[3634:99760] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/marcoalonso/Documents/SWIFT_PROJECTS/CircularProgressView/CircularProgressView/ViewController.swift, line 15

I have only 2 files which are:

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var containerView: UIView!
    var circularView: CircularProgressView!
    var duration: TimeInterval!
    override func viewDidLoad() {
        super.viewDidLoad()
        circularView.center = view.center
        containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
        view.addSubview(circularView)
    }

    @objc func handleTap() {
        duration = 3.0
        circularView.progressAnimation(duration: duration)
    }
}

and CircularProgressView.swift:

import UIKit
class CircularProgressView: UIView {
    // First create two layer properties
    private var circleLayer = CAShapeLayer()
    private var progressLayer = CAShapeLayer()
    override init(frame: CGRect) {
        super.init(frame: frame)
        createCircularPath()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createCircularPath()
    }
    func createCircularPath() {
        let circularPath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: 80, startAngle: -.pi / 2, endAngle: 3 * .pi / 2, clockwise: true)
        circleLayer.path = circularPath.cgPath
        circleLayer.fillColor = UIColor.clear.cgColor
        circleLayer.lineCap = .round
        circleLayer.lineWidth = 20.0
        circleLayer.strokeColor = UIColor.black.cgColor
        progressLayer.path = circularPath.cgPath
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.lineCap = .round
        progressLayer.lineWidth = 10.0
        progressLayer.strokeEnd = 0
        progressLayer.strokeColor = UIColor.red.cgColor
        layer.addSublayer(circleLayer)
        layer.addSublayer(progressLayer)
    }
    func progressAnimation(duration: TimeInterval) {
        let circularProgressAnimation = CABasicAnimation(keyPath: "strokeEnd")
        circularProgressAnimation.duration = duration
        circularProgressAnimation.toValue = 1.0
        circularProgressAnimation.fillMode = .forwards
        circularProgressAnimation.isRemovedOnCompletion = false
        progressLayer.add(circularProgressAnimation, forKey: "progressAnim")
    }
}

I hope someone can help me please!

I think maybe it`s a problem with storyboard so, this is my story board file enter image description here

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • `circularView.center = view.center` is not initialised when you make this call. You will have to create an instance of the view before you can interact with it. You will also need to add it to your view controller's view before you're likely to see it – MadProgrammer Apr 19 '20 at 00:45
  • Does this answer your question? [What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – jnpdx Jul 22 '21 at 22:36

3 Answers3

0

Here you're using a nil circularView to assign center property and that's fail

override func viewDidLoad() {
    super.viewDidLoad()
    circularView.center = view.center
    containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    view.addSubview(circularView)
}

You can remove that line and assign center when circularView is not nil or initialize circularView first and then use center.

Maetschl
  • 1,330
  • 14
  • 23
0

Just initialise circularView in your ViewController:

replace:

var circularView: CircularProgressView!

with:

var circularView = CircularProgressView()
gab
  • 1
0

You have not initialised any object for circularView. You have only said that circularView will have a object of type CircularProgressView but you have not stored any object there. So before doing anything using circularView initialise it with :

circularView = CircularProgressView() 

For more clearity your code should be like this

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var containerView: UIView!
    var circularView: CircularProgressView!
    var duration: TimeInterval!
    override func viewDidLoad() {
        super.viewDidLoad()
        circularView = CircularProgressView()
        circularView.center = view.center
        containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
        view.addSubview(circularView)
    }

    @objc func handleTap() {
        duration = 3.0
        circularView.progressAnimation(duration: duration)
    }
}