Yasir Ghafar
Yasir Ghafar

Reputation: 110

MKMapView is unexpectedly found nil while unwrapping an Optional value

I've written this function to draw an overlay on map and its working fine when I call it in viewDidLoad of MapViewController.

func drawTripLocations(locs: Array<Location>){
  var loclist: Array<CLLocationCoordinate2D> = []
             if (locs.count > 3){
                    for loc in locs{
                        if (loc.gps == 1){
                            let cord = CLLocationCoordinate2D(latitude: loc.lat!, longitude: loc.lon!)
                            loclist.append(cord)
                }
            }
        }

          if(loclist != nil && loclist.count > 1){

        /*   if let overlays = self.mainMapView?.overlays {
         self.mainMapView.removeOverlays(overlays)
         self.mainMapView.delegate = self
         }
         if let annotations = self.mainMapView?.annotations {
         self.mainMapView.removeAnnotations(annotations)
         self.mainMapView.delegate = self
         }*/

        let startmark = loclist.first
        let endmark = loclist.last


        let polyline = MKPolyline(coordinates: loclist, count: loclist.count)
            print(polyline.pointCount)
        let mapAnnotation = MKPointAnnotation();

        self.addDefaultMapPin("Start" , coordinates: startmark!)
        self.addDefaultMapPin("end" , coordinates: endmark!)

        self.mainMapView.add(polyline)
        zoomPolyline(polyline)

    }

}

I need to use this function to draw overlay according to new locations from a TableViewController for that I've written a function in this view controller:

    func getPathLocations(loclist: Array<Location>, stloc: Location, endloc: Location){

    var locations: Array<Location> = []

    if loclist != nil && loclist.count > 1{
        for loc in loclist{
            if((Double(loc.tm!) > Double(stloc.tm!) && loc.ign) && (Double(loc.tm!) <= Double(endloc.tm!)) ){
                locations.append(loc)
            }
        }
    }
    print(locations.count)

    let mainstoryboard: UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
            let mapViewController: MapViewController = mainstoryboard.instantiateViewController(withIdentifier: "MapViewController") as! MapViewController

        mapViewController.drawTripLocations(locs: locations)
}

The problem I'm facing is mainMapView object in drawTripLocations() is always nil when I call this function from other viewController.

Upvotes: 0

Views: 582

Answers (1)

Bilal
Bilal

Reputation: 19156

Yes because MapViewController view is not loaded yet and mainMapView is nil. View will be loaded when you push / present the view controller.

Option 1

Load view by accessing view property of UIViewController

let mainstoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let mapViewController = mainstoryboard.instantiateViewController(withIdentifier: "MapViewController") as! MapViewController
_ = mapViewController.view // this will make sure view is loaded
mapViewController.drawTripLocations(locs: locations)

Option 2 (Better one)

In yourMapViewController add a property

var locations:Array<Location>?

And set the locations (instead of calling drawTripLocations) before presenting / pushing MapViewController.

let mainstoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let mapViewController = mainstoryboard.instantiateViewController(withIdentifier: "MapViewController") as! MapViewController
mapViewController.locations = locations

And In viewDidLoad method of your MapViewController

override func viewDidLoad() {
    // other code
    if let locations = locations {
        drawTripLocations(locs: locations)
    }
}

Upvotes: 2

Related Questions