iosswiftviewcontrollerpresentmodalviewcontrollerpresentviewcontroller

IBOutlet References found nil when containing view controller is presented programmatically


I am building a running app and am trying to programmatically present a view controller when the start run button is tapped. However, when I tap the button after setting up the presenting view controller, any reference to an IBOutlet is found nil when unwrapping in the order that they are called.

It's worth noting that when I connect the two view controllers with "show" via storyboard instead, that everything works fine, but I want to present the view controller programmatically and in fullscreen rather than the cardlike presentation by default.

From the presenting view controller:

@IBAction func startRunTapped(_ sender: Any) {
    let inRunVC = CurrentRunVC()
    inRunVC.modalPresentationStyle = .fullScreen
    self.present(inRunVC, animated: true, completion: nil)
}

From the presented view controller:

import UIKit
import MapKit

class CurrentRunVC: LocationVC {


@IBOutlet weak var sliderImageView: UIImageView!
@IBOutlet weak var swipeBGImageView: UIImageView!
@IBOutlet weak var durationLabel: UILabel!
@IBOutlet weak var paceLabel: UILabel!
@IBOutlet weak var distanceLabel: UILabel!
@IBOutlet weak var pauseButton: UIButton!

var startLocation: CLLocation!
var lastLocation: CLLocation!
var timer = Timer()

var runDistance = 0.0
var pace = 0
var counter = 0

override func viewDidLoad() {
    super.viewDidLoad()
    let swipeGesture = UIPanGestureRecognizer(target: self, action: #selector(endRunSwiped(sender:)))
    sliderImageView.addGestureRecognizer(swipeGesture) //error unwrapping here
    sliderImageView.isUserInteractionEnabled = true    // and here
    swipeGesture.delegate = self as? UIGestureRecognizerDelegate
} 

//errors also on any other reference to an IBOutlet

I've confirmed that all IBOutlets are connected properly.

Storyboard:

enter image description here

Thanks in advance


Solution

  • You are not grabbing the correct storyboard instance of CurrentVC but you are creating a new one. Instead of let inRunVC = CurrentRunVC(), use

    let runVC = self.storyboard?.instantiateViewController(withIdentifier: "CurrentRunVC") as! CurrentRunVC //set the identifier in the storyboard identity inspector