How to Add a Button to the Mkpointannotation

How to add button to MKPointAnnotation in Swift

This can be accomplished by adding a UIButton to the rightCalloutAccessoryView of the MKPinAnnotationView.
Here is an example:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is MKUserLocation) {
let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))

let rightButton = UIButton(type: .contactAdd)
rightButton.tag = annotation.hash

pinView.animatesDrop = true
pinView.canShowCallout = true
pinView.rightCalloutAccessoryView = rightButton

return pinView
}
else {
return nil
}
}

This is what that'll look like:

Annotation View Button

Hope that helps you!

How to add a button to the MKPointAnnotation?

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.

Sample Image

How do I add button to MKPointAnnotation in Swift

Try the following code

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}

let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.canShowCallout = true

let rightButton: AnyObject! = UIButton(type: UIButton.ButtonType.detailDisclosure)
pinView?.rightCalloutAccessoryView = rightButton as? UIView
}
else {
pinView?.annotation = annotation
}

return pinView
}

Don't forget to set mapView's delegate

mapView.delegate = self

Add button to MKPointAnnotation

That answer in your first link is basically right, though it needs to be updated for Swift 2.

Bottom line, in answer to your question, you don't add the button when you create the annotation. You create the button when you create its annotation view in viewForAnnotation.

So, you should:

  1. Set the view controller to be the delegate of the map view.

  2. Make the view controller conform to the map view delegate protocol, e.g.:

    class ViewController: UIViewController, MKMapViewDelegate { ... }
  3. Add a segue from the view controller (not the button) to the next scene by control dragging from the view controller icon above the scene with the map view to the next scene:

    Sample Image

    Then select that segue and then give it a storyboard identifier ("NextScene" in my example, though you should use a more descriptive name):

    Sample Image

  4. Implement viewForAnnotation to add button as right accessory.

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    var view = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier)
    if view == nil {
    view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
    view?.canShowCallout = true
    view?.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure)
    } else {
    view?.annotation = annotation
    }
    return view
    }
  5. Implement calloutAccessoryControlTapped which (a) captures which annotation was tapped; and (b) initiates the segue:

    var selectedAnnotation: MKPointAnnotation!

    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
    if control == view.rightCalloutAccessoryView {
    selectedAnnotation = view.annotation as? MKPointAnnotation
    performSegueWithIdentifier("NextScene", sender: self)
    }
    }
  6. Implement a prepareForSegue that will pass the necessary information (presumably you want to pass the annotation and therefore have a annotation property in that second view controller).

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let destination = segue.destinationViewController as? SecondViewController {
    destination.annotation = selectedAnnotation
    }
    }
  7. Now you can create your annotation like you were before:

    let annotation = MKPointAnnotation()
    annotation.coordinate = coordinate
    annotation.title = "Title1"
    annotation.subtitle = "Subtitle1"
    mapView.addAnnotation(annotation)

Swift - adding a button to my MKPointAnnotation

Use the 'viewForAnnotation' map view delegate method to setup left and rightcalloutAccessories. and also UIButton.buttonWithType is replaced, this will work: Edit: all delegate methods you need but I didn't though your createAnnotation function because you said its working fine

class MapViewController: UIViewController, MKMapViewDelegate //
{
@IBOutlet weak var mapView: MKMapView!{ //make sure this outlet is connected
didSet{
mapView.delegate = self
}
}

// MARK: - Map view delegate

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
var view = mapView.dequeueReusableAnnotationViewWithIdentifier("AnnotationView Id")
if view == nil{
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "AnnotationView Id")
view!.canShowCallout = true
} else {
view!.annotation = annotation
}

view?.leftCalloutAccessoryView = nil
view?.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure)
//swift 1.2
//view?.rightCalloutAccessoryView = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as UIButton

return view
}

func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
//I don't know how to convert this if condition to swift 1.2 but you can remove it since you don't have any other button in the annotation view
if (control as? UIButton)?.buttonType == UIButtonType.DetailDisclosure {
mapView.deselectAnnotation(view.annotation, animated: false)
performSegueWithIdentifier("you're segue Id to detail vc", sender: view)
}
}
}

//Your function to load the annotations in viewDidLoad

}

How to add a button to an annotation, current solution not working

You need to add the delegate MKMapViewDelegate. And use the function,

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {

}


Related Topics



Leave a reply



Submit