Adding a button programmatically causes fatal error

I'm creating an object detection app and I currently have it generating bounding boxes around the results. I'd like to create a button each time a new object is detected to be able to navigate to a description page for that object. I generate the observations in a file outside of my View Controller but I'm creating the button in the ViewController. I know the title is not nil but I get a fatal error when I add a subview. Once an object is detected, I call:

Code Block swift
ViewController().showDetailView(buildingName: String(observationName))

And then in the View Controller it runs:

Code Block swift
public func showDetailView(buildingName: String){
let detailViewButton = UIButton()
detailViewButton.setTitle(buildingName, for: .normal)
detailViewButton.frame = CGRect(x:0, y:0, width:200, height: 100)
resultView.addSubview(detailViewButton)
_ = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: false) { timer in
detailViewButton.removeFromSuperview()
}
}

Finally, I receive this error once an object is detected:

Code Block swift
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

I've researched the problem and have found solutions (such as making sure the button is properly linked from the storyboard) but they don't seem to apply since I want to create the button programmatically.
I've also had suggestions that resultView is not initialized at the time that showDetailView() is called but it is displaying on the screen before I try to detect an object.
Swift uses ARC (automatic reference counting). You're creating a local variable for your button, but you're not retaining it and it gets deallocated after the function returns. Please try declaring the button as a variable in your view controller. It's probably best to declare it as an optional, because you're removing it from the screen after 10 seconds.
Note: In addition to the previous answer, I usually create the button with its frame, directly:

Code Block
let detailViewButton = UIButton(frame: CGRect(x:0, y:0, width:200, height: 100))

I don’t think this has anything to do with detailViewButton. The message says “while implicitly unwrapping”, not just “while unwrapping”, so that means that an implicitly-unwrapped optional is involved here. detailViewButton is not an IUO—it would have to be declared like let detailViewButton: UIButton! for it to be one—so I don’t think it’s the problem.

On the other hand, IUOs are often used for IBOutlets. Is resultView an IBOutlet? Is it declared with an ! in its type instead of a ?? If so, I’d encourage you to take another look at it.

I've also had suggestions that resultView is not initialized at the time that showDetailView() is called but it is displaying on the screen before I try to detect an object.

This doesn’t really prove much, though—if you’ve added the view to your storyboard but you forgot to connect it to the outlet, you would still see the view that you intended to use as resultView on the screen, but the outlet would be nil.

What I would do is add this to the top of your method:
Code Block swift
precondition(resultView != nil, "Result view should be connected")

It’s never a bad idea to state assumptions like this explicitly in a precondition—it makes them clear to anyone reading the code, and it also makes the message clearer if you made a mistake. And if the precondition fails when you add it, then you’ll know how what the bug is.
Adding a button programmatically causes fatal error
 
 
Q