0

I am switching tabBar programmatically - which works fine. However, an IBOutlet mapView (google maps) becomes nil - leading to a crash...

I've spent quite a few hours on this. Feels like I am missing something trivial. Looked through SO, e.g.: Switch tab bar programatically in Swift and All my IBOutlet are nil in viewDidLoad but with no luck.

Any help much appreciated!

App delegate

func goToTabRoot(){
    if let tabBarController = self.window!.rootViewController as? UITabBarController {
        let index = 0 // First (root) tab
        tabBarController.selectedIndex = index
        let vc = tabBarController.viewControllers![index] as! UINavigationController
        tabBarController.delegate?.tabBarController!(tabBarController, didSelectViewController:vc)
    }
}

Map View Controller

class MapViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate, BudgetTableViewControllerDelegate, StoreViewControllerDelegate, ProductPickedViewControllerDelegate {

@IBOutlet weak var mapView: GMSMapView!

override func viewDidAppear(animated: Bool) {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest // Best accuracy
    locationManager.requestWhenInUseAuthorization()
    mapView.delegate = self // <== ERROR HERE. mapView = nil

    println("ViewDidAppear called")
}


func favoriteViewDidFinish(controller: MapViewController, productIds: [Product]) {
    println("Favorite finished")

    // Select MapView
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.goToTabRoot()

    // Store product IDs
    self.productIds = productIds

    // Update stores (download)
    queryType = "filterProducts"
    downloadStores = true
    updateStores()

}

Products selected

protocol ProductPickedViewControllerDelegate: class {
    func favoriteViewDidFinish(controller: MapViewController, productIds: [Product])
}

class ProductPickedViewController: UIViewController, UITabBarControllerDelegate {

var delegate:ProductPickedViewControllerDelegate? = nil

@IBAction func storesButtonPressed(sender: AnyObject) {

    // Set delegate
    delegate = MapViewController() // First view controller

    // Download relevant stores
    println("Should reload stores...")
    if (self.delegate != nil) {
        println("activate delegate")
        self.delegate!.favoriteViewDidFinish(MapViewController(), productIds: productsPresented)
    }
Community
  • 1
  • 1
Peder Wessel
  • 646
  • 1
  • 9
  • 23

1 Answers1

1

The problem is that you're creating a new instance of MapViewController when you set the delegate with the below line. That instance isn't made in the storyboard, so it knows nothing about your IBOutlet.

delegate = MapViewController()

You need to get a reference to the controller that already exists. If ProductPickedViewController is one of the view controllers in the tab bar controller, you can do that like so,

delegate = self.tabBarController!.viewControllers[0] as! MapViewController
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • Thanks @rdelmar - makes a lot of sense. However I now get the error "Cannot assign a value of type 'MapViewController' to a value of type 'ProductPickedViewControllerDelegate?'". To confirm - the ProductPickedViewController is one of the VCs on the tab bar controller. Any thoughts how to remedy? – Peder Wessel Jun 01 '15 at 16:49
  • Got past previous comment by forcing downcast: `self.tabBarController!.viewControllers![0].viewControllers[0] as! MapViewController`. The first VC in tabBar is embedded in NavBar. THANKS AGAIN! Made my day!! – Peder Wessel Jun 01 '15 at 18:35