Hi I would like to get the index number when the user taps on the annotation. I have the following code..
class ShopLocation: NSObject, MKAnnotation{
var identifier = "Shop location"
var title: String?
var subtitle: String?
var coordinate: CLLocationCoordinate2D
init(name:String,lat:CLLocationDegrees,long:CLLocationDegrees,addInfo:String){
title = name
coordinate = CLLocationCoordinate2DMake(lat, long)
subtitle = addInfo
}
}
class LocationList: NSObject {
var shop = [ShopLocation]()
override init(){
shop += [ShopLocation(name:"t1", lat:35.673647,long:139.727686,addInfo:"info")]
shop += [ShopLocation(name:"t2", lat:35.671928,long:139.760815,addInfo:"info")]
shop += [ShopLocation(name:"t3", lat:35.713232,long:139.793467,addInfo:"info")]
}
The annotations are displayed on a map. I would like to get the index for example if t1 is tapped I get an index of 1.
I don't know what to write in
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
LocationList().shop.index(of: )
}
Thank you!
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
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
}
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.