I add a pin where a user touches with this code:
func addPin(tap: UITapGestureRecognizer) {
if (tap.state == UIGestureRecognizerState.Ended) {
var coordinate = mapView.convertPoint(tap.locationInView(mapView), toCoordinateFromView: mapView)
let address = addressAnnotationLogic.createWithCoordinate(coordinate)
mapView.addAnnotation(address)
routeLogic.addAddressAnnotation(address, toRoute: currentRoute!)
// reverse geocode
let pinLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(pinLocation!, completionHandler: {
(placemarks, error) -> Void in
if error != nil {
println("Reverse geocoder failed with error " + error.localizedDescription)
}
if placemarks.count > 0 {
let topResult = placemarks[0] as? CLPlacemark
self.addressAnnotationLogic.updateAnnotation(address, withPlacemark: topResult!)
}
})
}
}
My addressAnnotationLogic just creates a backing NSManagedObjectModel to save it, and my routeLogic just adds it to a route which is another NSManagedObjectModel. My delegate methods are pretty standard.
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is AddressAnnotation {
var annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "SimplePinIdentifier")
annotationView.enabled = true
annotationView.animatesDrop = true
annotationView.draggable = false
annotationView.pinColor = MKPinAnnotationColor.Red
annotationView.canShowCallout = true
return annotationView
}
return nil
}
After my first pin is added, if I touch the screen again, for some reason the initial pin moves just the slightest bit which doesn't seem right. It's more frustrating because later I draw an MKPolyline between points and then the pin will move just ever so slightly making the poly line look incorrect. What is this about? Why the pins move just a little bit after already being added to the MKMapView?
You should probably make the
coordinate
property in yourAddressAnnotation
classdynamic
.If this doesn't work, please post your code for the
AddressAnnotation
class and theupdateAnnotation
method.Here's what I think happens:
Your annotation first gets the
coordinate
that is translated from the screen coordinates of your first tap.Then, in the asynchronous completion handler of your geocoder invocation, your
updateAnnotation()
method is called.I assume that you update the
coordinate
of yourAddressAnnotation
to the coordinate of the nearest Placemark in there. Unfortunately, the Map View has probably already drawn your Pin at the original location when that update happens.When the coordinate is updated asynchronously, the Map View does not notice it. Only when it redraws the annotation (prompted by the next tap), it picks up the updated coordinate (so you see the move from the first tap coordinate to the nearest place mark's coordinate).
Now, the Map View is actually trying to be notified of changes in its annotation's coordinates so that it can automatically redraw at the new coordinates. For that it uses a technology called Key-Value-Observing. "Normal" Swift properties don't support that, however. Making them
dynamic
does.