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)
}
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