Mapkit in Swift, Part 2

MapKit in Swift, Part 2

The calloutAccessoryControlTapped delegate method must be named mapView(annotationView:calloutAccessoryControlTapped:).

You can't use your own name like pinPressed(...).

This applies to any delegate method and is dictated by the protocol.

So it should be:

func mapView(mapView: MKMapView!, annotationView: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

if control == annotationView.rightCalloutAccessoryView {
println("Disclosure Pressed!")
}
}

MapKit - Swift Example

There are two main problems with the code:

  1. The viewForAnnotation delegate method is not named correctly and so the map view will not call it. The method declaration which is currently this:

    func mapViewAnnot(mapViewAnnot: MKMapView!,
    ViewForAnnotation annotation: MKAnnotation!) ->MKAnnotationView {

    is wrong. It should be this instead:

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

    The method must be named mapView(mapView:viewForAnnotation:).

  2. The other problem is this line:

    var pinView = mapViewAnnot.dequeueReusableAnnotationViewWithIdentifier(reuseId)   as? MKPinAnnotationView

    The reference to some object named mapViewAnnot is meaningless and must be preventing the code from compiling. The line should be this:

    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView

Mapkit Pin Annotations with Swift

This is the Pin Annotation class. I understand what you are saying but i am too new in coding to actually translate your observations into code.

import Foundation
import UIKit
import MapKit

class PinAnnotation : NSObject, MKAnnotation {
private var coord: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)

var coordinate: CLLocationCoordinate2D {
get {
return coord
}
}

var title: String = ""
var subtitle: String = ""

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

Opening MapKit pin in Maps

Figured it out: I wasn't calling calloutAccessoryControlTapped in my main class. I added it and it with the code provided by Andrej:

func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let url = NSURL(string: "http://maps.apple.com/?q=\(lat),\(long)")
if UIApplication.sharedApplication().canOpenURL(url!) == true {
UIApplication.sharedApplication().openURL(url!)
}
}

Get center coordinates from MapKit and display in UILabel

Declare var center = "" at the top of your class with other declarations. In the method below, it should automatically change the value of center:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
center = mapView.centerCoordinate
}

When you press your button set the value of your label to the value of center.

self.yourLabelName.text = center

To display as "Latitude: ... Longitude: ..." do as follows:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
let mapLatitude = mapView.centerCoordinate.latitude
let mapLongitude = mapView.centerCoordinate.longitude
center = "Latitude: \(mapLatitude) Longitude: \(mapLongitude)"
print(center)
self.yourLabelName.text = center
}

If you want to format the coordinates to display a little more friendly:

center = "\(String(format: "%.5f", mapLatitude)), \(String(format: "%.5f", mapLongitude))"

Adjust the %.5f according to your preference of number of decimal places.

MapKit addAnnotation vs addAnnotations

The bit you're missing is that MKPointAnnotation is a reference type (a class) and that the map stores a reference to the instance of the class that you create. Therefore each time you attempt to add a new annotation you are actually updating the properties of the existing one, rather than creating and adding a new one. That's why it was always the last set of values that were visible.

To make your first example work you'd need to create a new MKMapAnnotation for each of the three annotations.

(I'm actually surprised the timer-based one works, as you still appear to updating the same object. I'll have a play with that one...)



Related Topics



Leave a reply



Submit