简体   繁体   中英

iOS - Swift - How to add a button to MKPointAnnotaton - MapKit

Currently I have a map view set up with 5 hardcoded locations which are shown on the map with pins. When the user clicks on these pins then a callout is show to the user which has details of the location. Within these callouts I am trying to include a button which the user can press and then takes them to another view controller.

Below is the current code I have, however when I tap on the pins no button is shown, does anyone have any idea what I am missing or what I need to do in order to implement the button?

Here is my code for the locations and the current user location.

import UIKit
import MapKit
import CoreLocation
import SceneKit

class SecondViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate
{
    @IBOutlet weak var mapView: MKMapView!

//Location manager property
let locationManager = CLLocationManager()

override func viewDidLoad()
{
    super.viewDidLoad()

    mapView.delegate = self

    //Find the current location as soon as the view is loaded
    self.locationManager.delegate = self

    //Setting the accuracy
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest

    //So only location services are used within the app
    self.locationManager.requestWhenInUseAuthorization()

    //Start up the location manager and find current location
    self.locationManager.startUpdatingLocation()

    //Use blue pin to show the location to the user
    self.mapView.showsUserLocation = true

    //Array of dictionaries to store the locations
    let locationData = [

        //Radio City Tower
        ["name": "Radio City Tower",
        "latitude": 53.4071551,
        "longitude": -2.980798600000071],

        //Metropolitian Cathedral
        ["name": "Metropolitian Catherdral",
         "latitude": 53.40494649999999,
         "longitude": -2.9684022999999797],

        //Walker Art Gallery
        ["name": "Walker Art Gallery",
            "latitude": 53.410068,
            "longitude": -2.979666],

        //Liver Buildings
        ["name": "Liver Buildings",
            "latitude": 53.405808,
            "longitude": -2.995859],

        //St George's Hall
        ["name": "St George's Hall",
            "latitude": 53.409277,
            "longitude": -2.979946]
    ]

    //Object for each dictionary in the locations array
    var annotations = [MKPointAnnotation]()

    //Populating the map with the location pins
    for Dictionary in locationData {
        let latitude = CLLocationDegrees(Dictionary["latitude"] as! Double)
        let longitude = CLLocationDegrees(Dictionary["longitude"] as! Double)
        let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
        let name = Dictionary["name"] as! String
        let annotation = MKPointAnnotation()

        //Apply to annotation
        annotation.coordinate = coordinate
        annotation.title = "\(name)"
        annotations.append(annotation)


    }

    mapView.addAnnotations(annotations)

}

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

// MARK: - Location Delegate Methods

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    //Gets the most current location
    let location = locations.last

     //gets the center of the last location
    let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)

    //Creatng a region - Map will zoom to this
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: Double(0.004), longitudeDelta: Double(0.004)))

    //Apply the map view to the region
    self.mapView.setRegion(region, animated: true)

    //Stop updating the location
    self.locationManager.stopUpdatingLocation()

    let currentLocation = CLLocationCoordinate2DMake(location!.coordinate.latitude, location!.coordinate.longitude)

    //Adding an annotation to current user location
    var pinAnnotation = MKPointAnnotation()

    //Set pin coordinate to the users current location
    pinAnnotation.coordinate = currentLocation

    //Annotation title
    pinAnnotation.title = "Current Location"

    //Annotation subtitle
    pinAnnotation.subtitle = "You are here!"

    //Add the pin to the mapView
    mapView.addAnnotation(pinAnnotation)

}

And here is the code for the button implementation within the callout(does not work)

    func MapView(mapview: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryTapped control: UIControl!) {
    if control == view.rightCalloutAccessoryView {
        print(view.annotation?.title)
        print(view.annotation?.subtitle)

        //Perform segue to navigate to viewcontroller
    }
}

func MapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    print("viewForAnnotation")
    if(annotation is MKUserLocation) {
        return nil
    }

    let reuseID = "pin"
    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID) as? MKPinAnnotationView

    if(pinView == nil) {
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseID)
        pinView!.canShowCallout = true
        pinView!.animatesDrop = true
    }

    var button = UIButton(type: .DetailDisclosure) as UIButton

    pinView?.rightCalloutAccessoryView = button

    return pinView

}

I am probably missing something really simple but I am not sure what. I am very new to iOS/Swift development and also MapKit so please bear with me. I also understand that this question has been asked multiple times however, I am still unable to solve this. Any help is appreciated, Thank you.

You are making a small mistake in the following callout method where you are explicitly unwrapped the MKAnnotationView! and MKMapView! . Here is the corrected one I have tested it.

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    print("viewForAnnotation")
    if(annotation is MKUserLocation) {
        return nil
    }
    let reuseID = "pin"
    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID) as? MKPinAnnotationView
    if(pinView == nil) {
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseID)
        pinView!.canShowCallout = true
        pinView!.animatesDrop = true
    }
    let button = UIButton()
    button.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    let image = UIImage(named: "img.png")
    button.setImage(image, forState: .Normal)
    pinView?.rightCalloutAccessoryView = button
    return pinView
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM