Find Index of Annotation Mapkit

Find index of annotation MapKit

I think the main problem here is that you expect that mapView.annotations returns an array with all annotations being in the same order as your detailsDict-Array. I think that this assumption is error prone, because it would highly depend on the internal implementation of the MapKit framework.

A better way would be storing the Dictionary entry together with the PlaceAnnotation that you add to the map:

  • Add a new property details to class PlaceAnnotation
  • Set details value when you create the PlaceAnnotation
  • in calloutAccessoryControlTapped, get back the details property from the PlaceAnnotation
  • transfer this value to detail controller (maybe via your selectedPlace property, but I would prefer in instatiating the ViewController directly and setting the value).

Get the array index from annotation

I assume ShopLocation already conforms to MKAnnotation, if not then make it conform and pass it to MKAnnotationView's initializer. This will make it available in the delegate method, via view.annotation

Now that you have access to the ShopLocation instance, there are two solutions that come to my mind for finding it's index in the shop

  1. Conform to Equatable - this will enable the firstIndex(of:) method of Array (actually of Collection to which Array conforms)

     extension ShopLocation: Equatable {
    static func ==(lhs: ShopLocation, rhs: ShopLocation) -> Bool {
    // place here the conditions for two instances to be equal
    }

    // ... later in the code

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    guard let shopLocation = view.annotation as? ShopLocation else {
    // this early returns if the annotation is not a shop location,
    // if you don't wan't that you can use an if-let instead
    return
    }
    let index = LocationList().shop.firstIndex(of: shopLocation)
    // do what you need with the index
    }
  2. Use the firstIndex(where:) method of Array (again, actually of Collection :)

     func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    guard let shopLocation = view.annotation as? ShopLocation else {
    // this early returns if the annotation is not a shop location,
    // if you don't wan't that you can use an if-let instead
    return
    }
    let index = LocationList().shop.firstIndex(where: { shopLocation in
    return // same conditions as for the Equatable
    })
    // do what you need with the index
    }

Personally, I'd recommend approach #1, even Apple recommends conforming value types to Equatable. Conforming to Equatable helps with code reduction, and enables lots of other functions besides the index(of:) mentioned here.

How to get Annotation index in Mapkit?

use this

 NSUInteger index = [mapView.annotations indexOfObject:view.annotation];
NSLog(@"index no %d",index);

you get the index

 NSInteger i = 0;
for (NSDictionary *row in locations) {
NSNumber *latitude = [row objectForKey:@"latitude"];
NSNumber *longitude = [row objectForKey:@"longitude"];
NSString *title = [row objectForKey:@"title"];
NSString * image=[row objectForKey:@"image"];
imageDic =[row objectForKey:image];
[customTickLocations addObject:[row objectForKey:@"image"]];

//Create coordinates from the latitude and longitude values
CLLocationCoordinate2D coord;
coord.latitude = latitude.doubleValue;
coord.longitude = longitude.doubleValue;

MapViewAnnotation * annotation =[[MapViewAnnotation alloc] initWithTitle:image initWithSubTitle:title AndCoordinate:coord Withindex:i];

i++;
[annotations addObject:annotation];

}

plz add one more property in MapViewAnnotation for index then try.

Find selected MapKit Annotation's postID

Try the following code:

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if let annotation = view.annotation as? EventAnnotation {
mapEventID = annotation.eventKey
}
}

Get indexPath of mapView annotation

MKAnnotationView * view = ...

NSUInteger index = [mapView.annotations indexOfObject:view.annotation];

How to access specific index of MKAnnotation

MKMapViewDelegate provides a delegate method mapView:annotationView:calloutAccessoryControlTapped: Implementing this method provides you with the MKAnnotationView of the MKAnnotation instance you're looking for. You can call the MKAnnotationView's annotation property to get the corresponding instance of the MKAnnotation.

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

@IBOutlet weak var mapView: MKMapView!

var sortedAnnotationArray: [MKAnnotation] = [] //create your array of annotations.

//your ViewDidAppear now looks like:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
for (var i = 0; i < latArray.count; i++) {
let individualAnnotation = Annotations(title: addressArray[i], coordinate: CLLocationCoordinate2D(latitude: latArray[i], longitude: longArray[i]))
mapView.addAnnotation(individualAnnotation)
//append the newly added annotation to the array
sortedAnnotationArray.append(individualAnnotation)
}
}

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
let theAnnotation = view.annotation
for (index, value) in enumerate(sortedAnnotationArray) {
if value === theAnnotation {
println("The annotation's array index is \(index)")
}
}
}
}

How can I detect which annotation was selected in MapView

For that you can use selected Annotation from didSelectAnnotationView, then store that annotation to instance variable and after that used annotation in your Button action method.

var selectedAnnotation: MKPointAnnotation?

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
self.selectedAnnotation = view.annotation as? MKPointAnnotation
}

func info(sender: UIButton) {
print(selectedAnnotation?.coordinate)
}

Edit: As of you have custom MKAnnotation class you need to use that.

var selectedAnnotation: Islands?

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
self.selectedAnnotation = view.annotation as? Islands
}

Z-index of iOS MapKit user location annotation

Update for iOS 14

I know it's an old post, but the question is still applicable and you end up here when typing it into your favorite search engine.

Starting with iOS 14, Apple introduced a zPriority property to MKAnnotationView. You can use it to set up the z-index for your annotations using predefined constants or floats.
Also, Apple made it possible to finally create the view for the user location on our own and provided MKUserLocationView as a subclass of MKAnnotationView.

From the documentation for MKUserLocationView:

If you want to specify additional configuration, such as zPriority,
create this annotation view directly. To display the annotation view,
return the instance from mapView(_:viewFor:).

The following code snippet shows how this can be done (add the code to your MKMapViewDelegate):

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

// Alter the MKUserLocationView (iOS 14+)
if #available(iOS 14.0, *), annotation is MKUserLocation {

// Try to reuse the existing view that we create below
let reuseIdentifier = "userLocation"
if let existingView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) {
return existingView
}
let view = MKUserLocationView(annotation: annotation, reuseIdentifier: reuseIdentifier)

view.zPriority = .max // Show user location above other annotations
view.isEnabled = false // Ignore touch events and do not show callout

return view
}

// Create views for other annotations or return nil to use the default representation

return nil
}

Note that per default, the user location annotation shows a callout when tapping on it. Now that the user location overlays your other annotations, you'd probably want to disable this, which is done in the code by setting .isEnabled to false.

Get Index of MKAnnotation in MapView.annotations Array

The recommended way of handling this is to make your own class that implements the MKAnnotation protocol and has a property that you can check during viewForAnnotations to see what colour to use. The annotations array from MKMapView is not guaranteed to be in the order in which you add annotations to the map. You may add annoy, annoy and then annoy but you may get back [anno2, anno3, anno1]. That's just the way it is and you can't change that. So, you could keep your own array of annotations that won't get rearranged. Or use the extra property idea if that will suit.

One thing you should not do is add more annotations during the viewForAnnotation function, that's really messed up.



Related Topics



Leave a reply



Submit