MKMapView does call didSelect callback only once - ios

I'm using a custom annotation in my mapkit project (in swift 3) to show multiple annotations on the map. It's showing and I can click on annotationn but only the first time. For openning the annotation again I need to click everywhere on the map and click again the annotation. Could anybody help me ? Thank you in advance.
Here are the functions I'm using:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation
{
return nil
}
var annotationView = self.map.dequeueReusableAnnotationView(withIdentifier: "Pin")
if annotationView == nil{
annotationView = AnnotationView(annotation: annotation, reuseIdentifier: "Pin")
annotationView?.canShowCallout = false
}else{
annotationView?.annotation = annotation
}
if (indexPin > 0) {
indexPin = indexPin - 1
let pin : PinAnnotation = pinAnotationList[indexPin]
annotationView?.image = UIImage(named: pin.imageName)
}
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)
{
if view.annotation is MKUserLocation
{
return
}
let pin = view.annotation as! PinAnnotation
if pin.userType == "O" {
if (currentLatitude == 0 || currentLatitude2 == 0) {
self.showAlert(self, message: "It's necessary to set origin and destiny addresses")
return
}
AppVars.DriverId = pin.userId
AppVars.VehicleId = pin.vehicleId
AppVars.LatitudeDriver = pin.coordinate.latitude
AppVars.LongitudeDriver = pin.coordinate.longitude
performSegue(withIdentifier: "callDriverPopupSegue", sender: self)
}
else {
let customView = (Bundle.main.loadNibNamed("AnnotationView", owner: self, options: nil))?[0] as! CustomCalloutView
var calloutViewFrame = customView.frame;
let point = CGPoint(x: calloutViewFrame.size.width/2 + 15,y :calloutViewFrame.size.height - 10)
calloutViewFrame.origin = point
customView.frame = calloutViewFrame;
customView.titleLabel.text = pin.title
view.addSubview(customView)
}
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
if (view.isKind(of: PinAnnotation.self))
{
for subview in view.subviews
{
subview.removeFromSuperview()
}
}
if (view.isKind(of: AnnotationView.self))
{
for subview in view.subviews
{
subview.removeFromSuperview()
}
}
}
Class PinAnnotation
import MapKit
class PinAnnotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var userId: Int!
var vehicleId:Int!
var userType: String!
var imageName: String!
var title: String!
init(coordinate: CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
Class AnnotationView
import MapKit
class AnnotationView: MKAnnotationView
{
}

I've found a solution ! The situation occurred when called performSegue(withIdentifier: "callDriverPopupSegue", sender: self) in didSelect because the annotation that was clicked keeped selected. So I add the code bellow in mapview controller to deselect the annotation and after that I was able to click for the second time.
override func viewWillAppear(_ animated: Bool) {
DispatchQueue.main.async {
for item in self.map.selectedAnnotations {
self.map.deselectAnnotation(item, animated: false)
}
}
}

Related

Detect longpress in MapView for SwiftUI

I have a MapView in SwiftUi and I am trying to add a pin annotation to it when a user long presses a location on the map. I see this can easily be accomplished in swift however I am using SwiftUI. I do not know how to add the long-press detector. A code example would be great.
My MapView
struct MapView: UIViewRepresentable {
#Binding
var annotations: [PinAnnotation]
let addAnnotationListener: (PinAnnotation) -> Void
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
view.delegate = context.coordinator
view.addAnnotations(annotations)
if annotations.count == 1 {
let coords = annotations.first!.coordinate
let region = MKCoordinateRegion(center: coords, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
view.setRegion(region, animated: true)
}
}
func makeCoordinator() -> MapViewCoordinator {
MapViewCoordinator(self)
}
}
MapViewCoordinator
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var mapViewController: MapView
init(_ control: MapView) {
self.mapViewController = control
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let annotation = view.annotation
guard let placemark = annotation as? MKPointAnnotation else { return }
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
//Custom View for Annotation
let identifier = "Placemark"
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
let button = UIButton(type: .infoDark)
annotationView.rightCalloutAccessoryView = button
return annotationView
}
}
}
The method to add a pin to a MapView
func addPinBasedOnGesture(gestureRecognizer:UIGestureRecognizer){
var touchPoint = gestureRecognizer.locationInView(mapView)
var newCoordinates = self.convertPoint(touchPoint, toCoordinateFromView: mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinates
mapView.addAnnotation(annotation)
}
Below solution adds a pin at the point where user long presses on the Map.
Add below method in MapViewCoordinator
#objc func addPinBasedOnGesture(_ gestureRecognizer:UIGestureRecognizer) {
let touchPoint = gestureRecognizer.location(in: gestureRecognizer.view)
let newCoordinates = (gestureRecognizer.view as? MKMapView)?.convert(touchPoint, toCoordinateFrom: gestureRecognizer.view)
let annotation = PinAnnotation()
guard let _newCoordinates = newCoordinates else { return }
annotation.coordinate = _newCoordinates
mapViewController.annotations.append(annotation)
}
and longPress gesture code in func makeUIView(context: Context) -> MKMapView {}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
let longPressed = UILongPressGestureRecognizer(target: context.coordinator,
action: #selector(context.coordinator.addPinBasedOnGesture(_:)))
mapView.addGestureRecognizer(longPressed)
return mapView
}
Find below modified parts of provided code to get required behaviour:
struct SUMapView: UIViewRepresentable {
// ... other your code here
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
let longPressed = UILongPressGestureRecognizer(target:
context.coordinator, action: #selector(addPin(gesture:)))
mapView.addGestureRecognizer(longPressed)
return mapView
}
// ... other your code here
}
class MapViewCoordinator: NSObject, MKMapViewDelegate {
// ... other your code here
#objc func addPin(gesture: UILongPressGestureRecognizer) {
// do whatever needed here
}
// ... other your code here
}

Swift Mapview Custom Call Out View with default map view pins

I believe this is going to be a really easy answer but I've been trying to figure out how I add a custom callout view with map views default pins. With my current code it seems I can only add an image as the MKPointAnnotation instead of the default pins. This first "viewFor annotation" is how I set up the default pins, while everything underneath is for the custom call out view... What I am trying to do is have my custom call out view with the default pins. Do I have to add a custom image pin if I want a custom call out view?
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "") {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:"")
annotationView.isEnabled = true
annotationView.canShowCallout = true
let btn = UIButton(type: .detailDisclosure)
annotationView.rightCalloutAccessoryView = btn
return annotationView
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }
var annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: "Pin")
if annotationView == nil{
annotationView = CustomBusinessCallOutAnnotatiion(annotation: annotation, reuseIdentifier: "Pin")
annotationView?.canShowCallout = false
}else{
annotationView?.annotation = annotation
}
annotationView?.image = UIImage(named: "car")
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if view.annotation is MKUserLocation { return }
let customAnnotation = view.annotation as! CustomBusinessPoint
let views = Bundle.main.loadNibNamed("CustomBusinessCallOut", owner: nil, options: nil)
let calloutView = views?[0] as! CustomBusinessCallOut
calloutView.businessName.text = customAnnotation.businessName
calloutView.businessStreet.text = customAnnotation.businessStreet
calloutView.businessState.text = customAnnotation.businessState
calloutView.businessDistance.text = customAnnotation.businessDistance
calloutView.center = CGPoint(x: view.bounds.size.width / 2, y: -calloutView.bounds.size.height * -0.0001)
view.addSubview(calloutView)
mapView.setCenter((view.annotation?.coordinate)!, animated: true)
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
if view.isKind(of: CustomBusinessCallOutAnnotatiion.self) {
for subview in view.subviews {
subview.removeFromSuperview()
}
}
}
You need not addSubView calloutView. You can use MKAnnotationView as Custom Callout.
e.g. You should arrange the source code
Implement subclass of MKAnnotation and MKAnnotationView.
class PinAnnotation : NSObject, MKAnnotation {
var coordinate : CLLocationCoordinate2D
var title: String?
var calloutAnnotation: CustomBusinessCallOut?
init(location coord:CLLocationCoordinate2D) {
self.coordinate = coord
super.init()
}
}
class CustomBusinessCallOut : NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String?
init(location coord:CLLocationCoordinate2D) {
self.coordinate = coord
super.init()
}
}
class CalloutAnnotationView : MKAnnotationView {
}
Implement mapView delegate methods.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
if annotation is PinAnnotation {
let reuseId = "Pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
}
else {
pinView?.annotation = annotation
}
return pinView
} else if annotation is CustomBusinessCallOut {
let reuseId = "Callout"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if pinView == nil {
pinView = CalloutAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.addSubview(UIImageView(image: UIImage(named: "car")))
}
else {
pinView?.annotation = annotation
}
return pinView
} else {
return nil
}
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
guard view.annotation is PinAnnotation else { return }
if let pinAnnotation = view.annotation as? PinAnnotation {
let calloutAnnotation = CustomBusinessCallOut(location: pinAnnotation.coordinate)
calloutAnnotation.title = pinAnnotation.title
pinAnnotation.calloutAnnotation = calloutAnnotation
mapView.addAnnotation(calloutAnnotation)
}
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
guard view.annotation is PinAnnotation else { return }
if let pinAnnotation = view.annotation as? PinAnnotation,
let calloutAnnotation = pinAnnotation.calloutAnnotation {
mapView.removeAnnotation(calloutAnnotation)
pinAnnotation.calloutAnnotation = nil
}
}

Swift: MapView calloutAccessoryControlTapped index

class MapViewController: UIViewController, MKMapViewDelegate, HomeModelProtocol {
var feedItems: NSArray = NSArray()
var selectedLocation : LocationModel = LocationModel()
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let initialLocation = CLLocation(latitude: 45.444958, longitude: 12.328463)
centerMapLocation(location: initialLocation)
mapView.delegate = self
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func itemsDownloaded(items: NSArray) {
feedItems = items
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
let regionRadus: CLLocationDistance = 1000
func centerMapLocation(location: CLLocation){
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadus, regionRadus)
mapView.setRegion(coordinateRegion, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//checkLocationAuthorizationStatus()
displayLocations()
}
func displayLocations(){
let i = feedItems.count
var x = 0
while x<i{
let item: LocationModel = feedItems[x] as! LocationModel
var poiCoodinates = CLLocationCoordinate2D()
poiCoodinates.latitude = CDouble(item.latitude!)!
poiCoodinates.longitude = CDouble(item.longitude!)!
let pin: MKPointAnnotation = MKPointAnnotation()
pin.coordinate = poiCoodinates
self.mapView.addAnnotation(pin)
pin.title = item.name
pin.subtitle = item.address
x = x+1
}
//return loc
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let view = MKMarkerAnnotationView(annotation: selectedLocation as? MKAnnotation, reuseIdentifier: "pin")
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.leftCalloutAccessoryView = UIButton(type: .detailDisclosure)
return view
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
print(control.tag)
selectedLocation = feedItems[0] as! LocationModel
performSegue(withIdentifier: "InformationSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get reference to the destination view controller
let detailVC = segue.destination as! InformationViewController
// Set the property to the selected location so when the view for
// detail view controller loads, it can access that property to get the feeditem obj
detailVC.selectedLocation = selectedLocation
}
}
This is my code.
I want to display the Location in the next Viewcontroller.
I need to get the index at feeditems[].
How can i get the index in:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
So how do i get the index, which Button is tapped. There are many objects that are placed in the map.
Thank you for help and sorry for my bad english, hope you guys understand me.
1.Define Sublass MKPointAnnotation.
class MyPointAnnotation: MKPointAnnotation {
var feedItem: LocationModel
}
2.Set MyPointAnnotation.feedItem to feedItem.
let item: LocationModel = feedItems[x] as! LocationModel
var poiCoodinates = CLLocationCoordinate2D()
poiCoodinates.latitude = CDouble(item.latitude!)!
poiCoodinates.longitude = CDouble(item.longitude!)!
let pin: MyPointAnnotation = MyPointAnnotation()
pin.coordinate = poiCoodinates
pin.feedItem = item // Important!
self.mapView.addAnnotation(pin)
3.Get feedItem in calloutAccessoryControlTapped delegate method.
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if let pin = view.annotation as? MyPointAnnotation {
print(pin.feedItem)
}
}
Sublass MKAnnotation add index property / object from feedItems array to the class and
see custom class MyAnnotation implemented there in swift customPinAnnotationButton
this idea but now i have only objective -c version
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"wqwqwqwqwqw . . .");
MyAnnotation*ann = view.annotation;
NSLog(#"nammemmeme : %#",ann.weatherItem);
[self performSegueWithIdentifier:#"showDetails" sender:ann.weatherItem];
}
1.Define subclasses for Annotation
class PointAnnotation: MKPointAnnotation {
var indexAnnotation = 0
}
2.Mapview Delegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isMember(of: MKUserLocation.self) {
return nil
}
let identifier = "myAnnotation"
var annotationView: MKAnnotationView?
annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.image = UIImage(named:"Golf Courses.png")
annotationView?.canShowCallout = true
let callButton = UIButton(type: .detailDisclosure)
annotationView?.rightCalloutAccessoryView = callButton
annotationView?.sizeToFit()
} else {
annotationView!.annotation = annotation
}
}
3.Callaccessory button taped go to next view contoller
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
let obj = kStoryboardShops.instantiateViewController(withIdentifier: "ShopDetailsViewController") as! ShopDetailsViewController
if let annotation = view.annotation as? PointAnnotation {
obj.dicDetails = arrayOfItems[annotation.indexAnnotation]
}
let nav = UINavigationController(rootViewController: obj)
self.present(nav, animated: true, completion: nil)
}
}

How to change selected pin image in Map Kit in Swift 3?

I have a map and on this map I have custom annotation pins. All pins have same custom image. When i click on a pin, i need to change this annotation's image. I was using Google Maps before:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
if marker.userData as? Int != nil {
let marker_tag = marker.userData as! Int
Datas.selectedMarkerIndex = marker_tag
if let selectedMarker = mapView.selectedMarker {
selectedMarker.icon = UIImage(named: "marker_gray")
}
mapView.selectedMarker = marker
marker.icon = UIImage(named: "marker_red")
}
return true
}
This was working fine. But I dont know how to do it with MapKit. I want to change just selected marker(pin) image. How can I do this?
Also I tried this but not working
How to change non selected annotation pin images on mapkit with Swift
And this is my code:
class CustomPointAnnotation: MKPointAnnotation {
var pinImageName:String!
var userData:Int!
}
extension MyView: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "my_pin"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
} else {
annotationView?.annotation = annotation
}
let customPointAnnotation = annotation as! CustomPointAnnotation
annotationView?.isDraggable = false
annotationView?.canShowCallout = false
annotationView?.layer.anchorPoint = CGPoint(x: 0.5, y: 1)
annotationView?.image = UIImage(named: customPointAnnotation.pinImageName)
return annotationView
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if let anno = view.annotation as? CustomPointAnnotation {
let marker_tag = anno.userData!
print(marker_tag)
}
}
func addMarkersOnMap(){
if Datas.myArray.count != 0 {
Datas.selectedMarkerIndex = 0
for i in 0..<Datas.myArray.count{
let lat = Datas.myArray[i].lat
let lng = Datas.myArray[i].lng
myArray.append(CustomPointAnnotation())
if lat != nil {
let location = CLLocationCoordinate2D(latitude: lat!, longitude: lng!)
myArray[i].pinImageName = "marker_gray"
myArray[i].coordinate = location
myArray[i].userData = i
pinAnnotationView = MKPinAnnotationView(annotation: myArray[i], reuseIdentifier: "my_pin")
mapView.addAnnotation(pinAnnotationView.annotation!)
}
}
"selected" means "tapped"? If so, Try the following code:
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
view.image = UIImage(named: "marker_gray")
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
view.image = UIImage(named: "marker_red")
}

How to add different button action to the second annotation /pin in map view using swift2

Can any one help me to add different button action to the second annotation /pin (annotation2), Now the button do the same work in the two annotation pins how to do different work to each other . I'am using Swift3 in my project and this is my code . thanks
This is my code.
import UIKit
import MapKit
import CoreLocation
class MyAnnotation: MKPointAnnotation {
var uniqueId: Int!
}
class LocationViewController: UIViewController , MKMapViewDelegate , CLLocationManagerDelegate{
#IBOutlet weak var map: MKMapView!{
didSet{
map.delegate = self
}
}
#IBOutlet weak var locationInfo: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
let locations = CLLocationCoordinate2DMake(33.314627, 44.303500)
let location2 = CLLocationCoordinate2DMake(33.312149, 44.3024567)
let span = MKCoordinateSpanMake(0.02, 0.02)
let span2 = MKCoordinateSpanMake(0.02, 0.02)
let region = MKCoordinateRegionMake(locations, span)
let region2 = MKCoordinateRegionMake(location2, span2)
map.setRegion(region, animated: true)
map.setRegion(region2, animated: true)
let annotation = MyAnnotation()
//annotation.setCoordinate(location)
annotation.coordinate = locations
annotation.title = "Zaid Homes"
annotation.subtitle = "Hay aljameaa"
annotation.uniqueId = 1
map.addAnnotation(annotation)
let annotation2 = MyAnnotation()
//annotation.setCoordinate(location)
annotation2.coordinate = location2
annotation2.title = "Zaid "
annotation2.subtitle = "aljameaa"
annotation.uniqueId = 2
map.addAnnotation(annotation2)
//Showing the device location on the map
self.map.showsUserLocation = true;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var view = mapView.dequeueReusableAnnotationView(withIdentifier: "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)
return view
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if (control as? UIButton)?.buttonType == UIButtonType.detailDisclosure {
mapView.deselectAnnotation(view.annotation, animated: false)
if let myAnnotation = view.annotation as? MyAnnotation {
if (myAnnotation.uniqueId == 1) {
performSegue(withIdentifier: "info", sender: view)
}
else {
performSegue(withIdentifier: "info2", sender: view)
}
}
}
}
}
The simplest way to know on which annotation you tap is using creating custom annotation class and adding annotation of it. So create one annotation class MyAnnotation child class of MKPointAnnotation and maintain one uniqueId with your multiple annotation.
class MyAnnotation: MKPointAnnotation {
var uniqueId: Int!
}
Now you need to add annotation of type MyAnnotation instead of MKPointAnnotation.
let annotation = MyAnnotation()
annotation.coordinate = locations
annotation.title = "Zaid Homes"
annotation.subtitle = "Hay aljameaa"
//Set uniqueId for annotation
annotation.uniqueId = 1
map.addAnnotation(annotation)
let annotation2 = MyAnnotation()
annotation2.coordinate = location2
annotation2.title = "Zaid "
annotation2.subtitle = "aljameaa"
//Set uniqueId for annotation
annotation2.uniqueId = 2
map.addAnnotation(annotation2)
Now check this uniqueId in calloutAccessoryControlTapped method on which annotation you tapped.
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if (control as? UIButton)?.buttonType == UIButtonType.detailDisclosure {
mapView.deselectAnnotation(view.annotation, animated: false)
if let myAnnotation = view.annotation as? MyAnnotation {
if (myAnnotation.uniqueId == 1) {
performSegue(withIdentifier: "info1", sender: view)
}
else {
performSegue(withIdentifier: "info2", sender: view)
}
}
}
}
you can do this by creating two subClass of MKPointAnnotation and then in the delegate's method you can do this :
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if view is subClass1 {
// do action for subclass 1
}
else if view is subClass2 {
// do action for subClass 2
}
}
Please let me know if this resolve your problem.
Update
you can make the implementation of you delegate more simpler like this exemple :
class ClassA:MKPointAnnotation{
func doActionWhenCalloutTapped(){
//do some action
}
}
class ClassB:ClassA{
override func doActionWhenCalloutTapped(){
//do some actions for annotation of type B
}
}
class ClassC:ClassA{
override func doActionWhenCalloutTapped(){
//do some actions for annotation of type C
}
}
func viewDidLoad(){
super.viewDidLoad()
let annotation = ClassB()
//annotation.setCoordinate(location)
annotation.coordinate = locations
annotation.title = "Zaid Homes"
annotation.subtitle = "Hay aljameaa"
map.addAnnotation(annotation)
let annotation2 = ClassC
//annotation.setCoordinate(location)
annotation2.coordinate = location2
annotation2.title = "Zaid "
annotation2.subtitle = "aljameaa"
map.addAnnotation(annotation2)
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
(view.annotation as! ClassA).doActionWhenCalloutTapped()
}

Resources