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:
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.
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:
Set the view controller to be the delegate of the map view.
Make the view controller conform to the map view delegate protocol, e.g.:
class ViewController: UIViewController, MKMapViewDelegate { ... }
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:
Then select that segue and then give it a storyboard identifier ("NextScene" in my example, though you should use a more descriptive name):
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
}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)
}
}Implement a
prepareForSegue
that will pass the necessary information (presumably you want to pass the annotation and therefore have aannotation
property in that second view controller).override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let destination = segue.destinationViewController as? SecondViewController {
destination.annotation = selectedAnnotation
}
}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
App Not Sized Properly iOS 8 iPhone Simulator
How to Make View the Size of Another View in Swiftui
How to Retrieve a File Using Wkwebview
How to Run the iOS 7.1 Simulator in Xcode 7.0 Beta 2
Is a Date in Same Week, Month, Year of Another Date in Swift
How Much Delay of iOS Push Notification
Segue in Skscene to Uiviewcontroller
How to Create a Hex Color String Uicolor Initializer in Swift
Swift Image Retrieving from Parse Sdk - Getting Crashed
How to Disable/Remove Firebaseanalytics
Does This App Use the Advertising Identifier (IDFA)? - Admob 6.8.0
Native Facebook App Does Not Open with Facebook Login in iOS 9
Programmatically Dial a Phone Number and Pass Dtmf Using the iPhone Sdk
Change Language of Alert in Banner of Push Notification
Launch Image Not Showing Up in iOS Application (Using Images.Xcassets)