Search code examples
iosswiftparse-platformmkannotationmkpointannotation

MapKit annotation button not showing up


I'm trying to build an app for iOS 8 using Swift which uses a Parse.com database to display pins on a MapView. I've succeeded in loading all the pins on the map us PFGeoPoints, but I'm trying to add a disclosure button to each pin which will perform a segue to show extra info.

I've double checked my code but I'm missing something, does anyone notice problems?

import UIKit
import Foundation
import Parse
import MapKit
import CoreLocation

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

let locationManager = CLLocationManager()
var userLocationParse = PFGeoPoint(latitude: 47.49, longitude: 19.06)

@IBOutlet weak var nmapview: MKMapView!

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager.requestWhenInUseAuthorization()
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()
    let location = CLLocationCoordinate2D(latitude: 47.49, longitude: 19.06)

    let span = MKCoordinateSpanMake(0.03, 0.03)
    let region = MKCoordinateRegion(center: location, span: span)
    nmapview.setRegion(region, animated: true)
    nmapview.showsPointsOfInterest = false
    nmapview.showsUserLocation = true
    displayMarkers()

}

func displayMarkers() -> Void {

    //GET PIN DATA HERE

    var query = PFQuery(className: "Places")
    query.whereKey("PlaceLocation", nearGeoPoint: userLocationParse)
    query.limit = 30

    let foundPlaces = query.findObjects()

    //GETTING PFGEOLOCATIONS AND PUTTING THEM ON MAP AS ANNOTATIONS
    //Loading pin details

    var annotationQuery = PFQuery(className: "Places")
    annotationQuery.whereKey("PlaceLocation", nearGeoPoint: userLocationParse)
    annotationQuery.findObjectsInBackgroundWithBlock {
        (posts, error) -> Void in
        if error == nil {
            // The find succeeded.
            //println("Successful query for annotations")
            let myPosts = posts as! [PFObject]

            for post in myPosts {


                let pinAnnotation = PinAnnotation()
                let point = post["PlaceLocation"] as! PFGeoPoint
                let pointName = post["PlaceName"] as! String
                let pointDetails = post["PlaceDetails"] as! String
                let thePinsLocation = CLLocationCoordinate2DMake(point.latitude, point.longitude)

                pinAnnotation.setCoordinate(thePinsLocation)
                pinAnnotation.title = pointName
                pinAnnotation.subtitle = pointDetails


                self.nmapview.addAnnotation(pinAnnotation)

            }
        } else {
            // Log details of the failure
            // println("Error: \(error)")
        }
    }

}

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

    if annotation is PinAnnotation {

        if annotation is MKUserLocation {
            //return nil so map view draws "blue dot" for standard user location
            return nil
        }

        let reuseID = "myPin"

        var pinAnnotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID) as? MKPinAnnotationView

        if pinAnnotationView == nil {

            pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseID)
            pinAnnotationView!.pinColor = .Purple
            pinAnnotationView!.canShowCallout = true
            pinAnnotationView!.animatesDrop = true

            pinAnnotationView!.rightCalloutAccessoryView = UIButton.buttonWithType(.DetailDisclosure) as! UIButton

        } else {
            pinAnnotationView!.annotation = annotation
        }

        return pinAnnotationView
    }

    return nil
}

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
    if control == view.rightCalloutAccessoryView{
       performSegueWithIdentifier("infoViewController", sender: self)
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

Also I created a class for "PinAnnotation" for use with the pins. Not sure if redundant but some tutorials on the subject brought it up as necessary.

import UIKit
import MapKit
import UIKit

class PinAnnotation: NSObject, MKAnnotation {

    private var coord: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 90.0, longitude: 0.0)

    var coordinate: CLLocationCoordinate2D {
        get {
            return coord
        }
    }

    var title: String = "North Pole"
    var subtitle: String = "Santa's house"

    func setCoordinate(newCoordinate: CLLocationCoordinate2D) {
        self.coord = newCoordinate
    }

}

Solution

  • On the basis of what you describe, it sounds like the delegate of the map view has not been set. You can set it in IB by going to the outlets inspector. You can set it programmatically with:

    nmapview.delegate = self