Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a button to the MKPointAnnotation?

I've just got stuck trying to add a detail button to my annotation point, unfortunately I don't know how to do it. Does anyone could help me with that?

The image below presents what I'd like to achieve. Thanks! enter image description here

MapKitViewController:

import UIKit
import MapKit
import CoreLocation

class MapKitViewController: UIViewController, MKMapViewDelegate
{

let locationManager = CLLocationManager()

@IBOutlet weak var nmapView: MKMapView!
override func viewDidLoad()
{
    super.viewDidLoad()
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
    let location = CLLocationCoordinate2D(
        latitude: 53.4265107,
        longitude: 14.5520357)

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

func displayMarkers() -> Void
{
    let jsonURL: NSURL = NSURL(string: "http://jsonstring.com/")!

    var dataFromNetwork: NSData = NSData(contentsOfURL: jsonURL)!
    let json = JSON(data: dataFromNetwork)
    var jsonSize = json.count

    var todaysDate:NSDate = NSDate()
    var dateFormatter:NSDateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    var formattedDate:String = dateFormatter.stringFromDate(todaysDate)

    let annotationView = MKAnnotationView()
    let detailButton: UIButton = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as UIButton
    annotationView.rightCalloutAccessoryView = detailButton


    for(var i = 0; i < jsonSize; i++)
    {
        if(json[i]["rozpoczecie"].stringValue == formattedDate)
        {
            let clubID = json[i]["id_klub"].stringValue
            let annotation = MKPointAnnotation()
            let (resultSet, err) = SD.executeQuery("SELECT * FROM Clubs WHERE ID = ?", withArgs: [clubID])
            if(err != nil){println("blad")}
            else
            {
                for row in resultSet
                {
                    let name = row["Name"]?.asString()
                    let latitude = row["Latitude"]?.asDouble()
                    let longitude = row["Longitude"]?.asDouble()
                    annotation.title = name
                    var markerLatitude: Double = latitude!
                    var markerLongitude: Double = longitude!
                    let location = CLLocationCoordinate2D(latitude: markerLatitude, longitude: markerLongitude)
                    annotation.setCoordinate(location)
                    annotation.subtitle = json[i]["nazwa"].stringValue
                }
                nmapView.addAnnotation(annotation)
            }
        }
    }
}
like image 970
wtznc Avatar asked Jan 29 '15 21:01

wtznc


1 Answers

You are doing it right.You just need to have these methods implemented for adding button along with title and subtitle

iOS 8 and Xcode 6

 import UIKit
 import MapKit
 import CoreLocation

 class MapKitViewController: UIViewController, MKMapViewDelegate
 {
    let locationManager = CLLocationManager()
    @IBOutlet weak var nmapView: MKMapView!
    override func viewDidLoad()
    {
        super.viewDidLoad()
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
        let location = CLLocationCoordinate2D(
            latitude: 53.4265107,
            longitude: 14.5520357)

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

    // When user taps on the disclosure button you can perform a segue to navigate to another view controller
    func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
        if control == view.rightCalloutAccessoryView{
            println(view.annotation.title) // annotation's title
            println(view.annotation.subtitle) // annotation's subttitle

            //Perform a segue here to navigate to another viewcontroller
            // On tapping the disclosure button you will get here
        }
    }

    // Here we add disclosure button inside annotation window
    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        println("viewForannotation")
        if annotation is MKUserLocation {
            //return nil 
            return nil
        }

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

        if pinView == nil {
            //println("Pinview was nil")
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView!.canShowCallout = true
            pinView!.animatesDrop = true
            }

        var button = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as UIButton // button with info sign in it

        pinView?.rightCalloutAccessoryView = button


        return pinView
    }


    func displayMarkers() -> Void
    {
        let jsonURL: NSURL = NSURL(string: "http://atnight.wtznc.com/json.php")!

        var dataFromNetwork: NSData = NSData(contentsOfURL: jsonURL)!
        let json = JSON(data: dataFromNetwork)
        var jsonSize = json.count

        var todaysDate:NSDate = NSDate()
        var dateFormatter:NSDateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        var formattedDate:String = dateFormatter.stringFromDate(todaysDate)

        let annotationView = MKAnnotationView()

        // Adding button here wont do anything  so remove these two lines


        let detailButton: UIButton = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as UIButton
        annotationView.rightCalloutAccessoryView = detailButton

        // For adding button we have to use a method named as viewForAnnotation 

        for(var i = 0; i < jsonSize; i++)
        {
            if(json[i]["rozpoczecie"].stringValue == formattedDate)
            {
                let clubID = json[i]["id_klub"].stringValue
                let annotation = MKPointAnnotation()
                let (resultSet, err) = SD.executeQuery("SELECT * FROM Clubs WHERE ID = ?", withArgs: [clubID])
                if(err != nil){println("blad")}
                else
                {
                    for row in resultSet
                    {
                        let name = row["Name"]?.asString()
                        let latitude = row["Latitude"]?.asDouble()
                        let longitude = row["Longitude"]?.asDouble()
                        annotation.title = name
                        var markerLatitude: Double = latitude!
                        var markerLongitude: Double = longitude!
                        let location = CLLocationCoordinate2D(latitude: markerLatitude, longitude: markerLongitude)
                        annotation.setCoordinate(location)
                        annotation.subtitle = json[i]["nazwa"].stringValue
                    }
                    nmapView.addAnnotation(annotation)
                }
            }
        }
    }
}

Check out my output.

enter image description here

like image 171
Talha Q Avatar answered Sep 28 '22 07:09

Talha Q