путаница в viewForAnnotation и итеративная настройка pinColor
Цель состоит в том, чтобы настроить цвета выводов для некоторых значений, хранящихся в структурном массиве.
Для некоторой помощи здесь я реализовал следующий метод делегата viewForAnnotation, и он прекрасно работает, вызывая этот метод делегата итеративно в цикле, основанном на размере моего массива данных структуры. Так что это работает, если я хочу установить все контакты на один цвет, например, фиолетовый (который является закомментированной строкой в коде ниже).
Проблема в том, что, когда я вставляю переключатель для установки цвета на основе значения в моем массиве, он проходит через этот код, но не учитывает значения регистра, чтобы установить его на альтернативный цвет, и все идет к красному выводу (по-видимому, по умолчанию). Я распечатал статус и отладил, чтобы знать, что он попадает внутрь коммутатора и соответственно настраивает pinColor, но они, похоже, не залипают.
func mapView(aMapView: MKMapView!,
viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
let theindex = mystructindex // grab the index from a global to be used below
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = aMapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
//println("Pinview was nil")
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
// Preventive if to keep this from being called beyond my arrays index value as the delegate getting called beyond the for loop for some unknown reason
if (theindex < MySupplierData.count) {
// Set the pin color based on the status value in MySupplierData structure array
switch MySupplierData[mystructindex].status {
case 0,1:
println("Case 0 or 1 - setting to Red")
pinView!.pinColor = .Red // Needs help, show red pin
case 2:
println("Case 2 - Setting to Green")
pinView!.pinColor = .Green // Looking Good
case 3:
println("Case 3 - Setting to Purple")
pinView!.pinColor = .Purple // Could use a follow-up
default:
println("Case default - Should Never Happen")
break;
} // end switch
} // end if
// pinView!.pinColor = .Purple // This works fine without the switch and respects any color I set it to.
}
else {
pinView!.annotation = annotation
}
return pinView
}
Внутри моего цикла for внутри ViewController я вызываю это следующим образом, но я ничего не делаю с возвращением.
// previous to this I setup some Titles and Subtitle which work fine
self.theMapView.addAnnotation(myAnnotation)
// Call to my mapview
mapView(theMapView, viewForAnnotation: myAnnotation)
Я ничего не делаю с возвратом Pinview - не думал, что мне нужно, но все контакты на этом этапе закрашиваются красным при использовании кода переключателя. По сути, я должен что-то здесь упустить.
7-8-14 Обновления для решения проблем с исправленным кодом в соответствии с большой помощью / обучением Анны. TKS!
Это почти работает, все выводы на карте имеют правильные цвета, но те, которые находятся за пределами непосредственного отображения, иногда неверны. Размещение всего кода, включенного здесь, поскольку это может помочь другим, так как это, кажется, очень распространенный вопрос о том, как выполнять пользовательскую работу в Картах.
Пользовательский класс, как предлагается для хранения другой переменной в пользовательской аннотации - в этом случае значение состояния исходит из моей структуры данных, MySupplierData.
class CustomMapPinAnnotation : NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var title: String
var subtitle: String
var status: Int
init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String, status: Int) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
self.status = status
}
}
Пересмотренный mapView - теперь с использованием новой CustomMapPinAnnotation, передаваемой ему:
func mapView(aMapView: MKMapView!,
viewForAnnotation annotation: CustomMapPinAnnotation!) -> MKAnnotationView! {
let reuseId = "pin"
var pinView = aMapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
//println("Pinview was nil")
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
// Code to catch my custom CustomMapPinAnnotation so we can check the status and set the color
if annotation.isKindOfClass(CustomMapPinAnnotation)
{
println("FOUND OUR CustomMapPinAnnotation CLASS IN mapView")
println(" Custom Title = \(annotation.title)")
println(" Custom status passed = \(annotation.status)")
switch annotation.status {
case 0,1:
println("Case 0 or 1 - Setting to Red")
pinView!.pinColor = .Red
case 2:
println("Case 2 - Setting to Green")
pinView!.pinColor = .Green
case 3:
println("Case 3 - Setting to Purple")
pinView!.pinColor = .Purple
default:
println("Case default - Should Never Happen")
break;
} // switch
} // if
}
else {
pinView!.annotation = annotation
}
return pinView
} //func mapView
В viewDidLoad настройки и цикл For для установки аннотаций
override func viewDidLoad() {
super.viewDidLoad()
// setup the region and Span
var theSpan:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
// Set the region to the the first element of the structure array.
var theRegion:MKCoordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(MySupplierData[0].latitude, MySupplierData[0].longitude), theSpan)
// This set the Map Type (Standard, Satellite, Hybrid)
self.theMapView.mapType = MKMapType.Standard
// Now loop through the structure data from 1 top the end of the structure to map the data
var mytitle: String = ""
var mysubtitle: String = ""
var myCustomPinAnnotation: CustomMapPinAnnotation
for mystructindex = 0; mystructindex < MySupplierData.count; ++mystructindex {
println("INSIDE SUPPLIER LOOP INDEX = \(mystructindex)" )
switch MySupplierData[mystructindex].status {
case 0:
mytitle = "(Red) " + MySupplierData[mystructindex].company
case 1:
mytitle = "(Red) " + MySupplierData[mystructindex].company
case 2:
mytitle = "(Geeen) " + MySupplierData[mystructindex].company
case 3:
mytitle = "(Purple) " + MySupplierData[mystructindex].company
default:
mytitle = "? " + MySupplierData[mystructindex].company
}
mysubtitle = MySupplierData[mystructindex].subtitle
// Create the Custom Annotations with my added status code
myCustomPinAnnotation = CustomMapPinAnnotation(
coordinate: CLLocationCoordinate2DMake(MySupplierData[mystructindex].latitude,MySupplierData[mystructindex].longitude),
title: mytitle, // custom title
subtitle: mysubtitle, // custom subtitle
status: MySupplierData[mystructindex].status) // status that will drive pin color
// put this annotation in the view.
self.theMapView.addAnnotation(myCustomPinAnnotation)
} // For
// This line brings up the display with the specific region in mind, otherwise it seems to default to a US Map.
self.theMapView.setRegion(theRegion, animated: true)
} // viewDidLoad
Отладочный вывод показывает, что цикл For выполняется до завершения, как и ожидалось, для создания myCustomPinAnnotation's, прежде чем пользовательский viewForAnnotation в mapView будет выполнен сам по себе. Когда я перемещаю карту в области за пределами непосредственного вида, я отмечаю, что viewForAnnotation в mapView вызывается по мере необходимости, и я вижу, что мой переключатель работает соответствующим образом, но цвета выводов не всегда правильные. Все контакты в исходной карте отображения правильны каждый раз, поэтому я остановился на этих внешних областях, чтобы понять, почему они отключены.