0

I have this:

guard let mapVC = mapSB.instantiateInitialViewController() else { return }

mapVC.navigationItem.title = "Some title string"
//        (mapVC as! MapViewController).string = "Some string"
//        (mapVC.navigationController?.viewControllers.first as! MapViewController).string = "Some string"

I have tried both of the commented out lines, but it crashes on whichever line I comment back in. And here is the po of mapVC:

po mapVC
error: <EXPR>:3:1: error: use of unresolved identifier 'mapVC'
mapVC
^~~~~~~~~

Which is weird, because it does correctly set the mapVC.navigationItem.title as "Some title string."

If this helps, mapVC is embedded in a navigation controller in mapSB.

Edit:

The crash message is:

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

And mapVC is of type MapViewController, hence the casting.

Latcie
  • 701
  • 1
  • 7
  • 21

2 Answers2

0

Instead of embedding that view controller in a navigation controller within that storyboard (which is probably not being picked up because you are expecting your instantiateViewController to return a MapViewController), try creating the navigation controller programatically, like this:

guard let mapVC = mapSB.instantiateInitialViewController() as? MapViewController else { fatalError("couldn't load MapViewController") }
mapVC.navigationItem.title = "Some title string"

// assuming mapVC has a .string property
mapVC.string = "Some string"

let navController = UINavigationController(rootViewController: mapVC) // Creating a navigation controller with mapVC at the root of the navigation stack.
self.presentViewController(navController, animated:true, completion: nil)

more information can be seen in this related question.

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
0

Try this instead.

    guard let navigationVC = mapSB.instantiateInitialViewController() as? UINavigationController,
        let mapVC = navigationVC.viewControllers.first as? MapViewController else {
            return
    }

    mapVC.navigationItem.title = "Some title string"
    mapVC.string = "Some string"

If your initial MapViewController is embedded in an UINavigationController, then mapSB.instantiateInitialViewController() is going to return the embedding UINavigationController instance. So you'll need to call navigationVC.viewControllers.first to get at your MapViewController instance.

In your initial code, the line

    (mapVC as! MapViewController).string = "Some string"

failed because mapVC wasn't an instance of MapViewController, so using as! MapViewController caused a crash.

The as! operator was also causing the crash in this line

    (mapVC.navigationController?.viewControllers.first as! MapViewController).string = "Some string"

Since mapVC is the root navigation controller, mapVC.navigationController evaluates to nil. Therefore mapVC.navigationController?.viewControllers.first resolves to nil, and trying to force conversion of nil with as! MapViewController results in a crash.

M.J.
  • 1,356
  • 1
  • 8
  • 3