David Andrews
David Andrews

Reputation: 1

MKPinAnnotationView doesn't show in MKMapView even though it's properly added using Swift

I'm developing an OSX app.

I've subclassed a MKAnnotation:

import Foundation
import MapKit

class LocationAnnotation: NSObject, MKAnnotation {

    var image: NSImage?
    var title: String?
    var coordinate: CLLocationCoordinate2D

    init(image anImage: NSImage?, title aTitle: String, coordinate aCoordinate: CLLocationCoordinate2D) {
        self.image = anImage
        self.title = aTitle
        self.coordinate = aCoordinate
    }
}

In my NSViewController subclass, I've added a MKMapViewDelegate and in Interface Builder I've added a MKMapView and set its delegate to NSViewController.

To find out what's wrong, I'm adding three locations in my ViewDidLoad method, into an array. I'm adding those annotations to my map in ViewDidAppear. I plan to move that to a background thread when I figure out what's wrong.

import Cocoa
import MapKit

class ShowLocationsViewController: NSViewController, MKMapViewDelegate {

    @IBOutlet var locationMap: MKMapView!

    private var myLocationArray: [LocationAnnotation] = []
    private var myRegion: MKCoordinateRegion!

    //#MARK: - UIViewController

    override func viewDidLoad() {
        super.viewDidLoad()

        myLocationArray = []
        myRegion = nil

        let locLondon = LocationAnnotation(image: nil, title: "London", coordinate: CLLocationCoordinate2DMake(51.522617, -0.139371))
        let locWembley = LocationAnnotation(image: nil, title: "Wembley", coordinate: CLLocationCoordinate2DMake(51.555909, -0.279600))
        let locGreenwich = LocationAnnotation(image: nil, title: "Greenwich", coordinate: CLLocationCoordinate2DMake(51.476572, -0.001596))

        myLocationArray.append(locLondon)
        myLocationArray.append(locWembley)
        myLocationArray.append(locGreenwich)

        myRegion = MKCoordinateRegion.init(center: locLondon.coordinate, span: MKCoordinateSpanMake(0.20, 0.20)) // 20km span
    }

    override func viewDidAppear() {
        locationMap.addAnnotations(myLocationArray)
        locationMap.setRegion(myRegion, animated: true)
    }
}

When using delegate's method viewFor annotation: I print out the title of each annotation in a log and all three of them are listed. In another delegate's method didAdd I'm printing out the number of annotations of my map in a log and it prints out three. But on my map, there are no annotations displayed. I tried panning and zooming with no success. Region gets properly set and displayed though.

//#MARK: - MKMapViewDelegate

func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
    print(locationMap.annotations.count, views.count)
}

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is LocationAnnotation {
        let annotationIdentifier = "Location"

        var annotationView = locationMap.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) as! MKPinAnnotationView?
        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
        }

        annotationView!.canShowCallout = true

        print(annotationView!.annotation!.title ?? "no view")

        return annotationView
    } else {
        print("no annotation")
        return nil
    }
}

When I try the same code in an iOS app, everything works. I assume there is nothing wrong with my delegate because methods are properly called.

I would appreciate any help you can give me.

Upvotes: 0

Views: 386

Answers (1)

David Andrews
David Andrews

Reputation: 1

I figured out the problem, the way the window is being called.

I created a variable mainWindowController in my AppDelegate, then I subclassed my main NSViewController so that I could hook up AppDelegate to it.

let appDelegate = NSApp.delegate as! AppDelegate
appDelegate.mainWindowController = self

Afterwards I used this code to call my window which was errornous:

let mapViewController = mainWindowController?.storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier.init(rawValue: "ShowLocationsID")) as! ShowLocationsViewController
mainWindowController?.contentViewController?.presentViewControllerAsModalWindow(mapViewController)

I changed that in a way that I created a segue in my storyboard and called the following code which worked and my pins did show:

performSegue(withIdentifier: NSStoryboardSegue.Identifier(rawValue: "ShowLocations"), sender: self)

Upvotes: 0

Related Questions