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