viewForAnnotation混淆和反复定制pinColor

目标是根据存储在结构数组中的某些值自定义引脚颜色。

在这里的一些帮助我实现了下面的viewForAnnotation委托方法,这很好地调用这个委托方法迭代在基于我的结构数据数组的大小循环。 所以,如果我想把所有的引脚设置为一种颜色,例如紫色(这是下面代码中的注释行),它就可以工作。

问题是当我把一个开关设置颜色基于我的数组中的值它通过这个代码,但不尊重任何案件的价值将其设置为一个替代的颜色,一切都去红针(看似默认)。 我已经打印出状态并进行debugging,知道它正在进入开关并设置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 } 

在ViewController中的for循环内部,我按照如下方式调用它,但是我没有对返回做任何事情。

  // 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!

它几乎工作,地图中的所有引脚都有正确的颜色,但是直接显示之外的引脚有时是错误的。 发布所有涉及的代码,因为这可能会帮助其他人,因为这似乎是一个关于如何在Maps中进行自定义工作的常见问题。

build议自定义类来保存自定义注释中的其他variables – 在这种情况下,状态值来自我的数据结构,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 

在viewDid中加载设置和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 

debugging输出显示For循环执行完成,以便在mapView中的自定义viewForAnnotation被内部执行之前创buildmyCustomPinAnnotation。 当我将地图移动到即时视图之外的区域时,我会注意到,viewView中的viewForAnnotation会根据需要被调用,并且我看到我的开关相应地执行,但是引脚颜色并不总是正确的。 初始显示地图中的所有引脚每次都是正确的,所以这些外部地区的引脚现在被卡住了。

首先 ,代码应该显式调用viewForAnnotation本身。
addAnnotation行之后删除对viewForAnnotation的显式调用。

viewForAnnotation是一个委托方法,当需要显示注解时, 地图视图会自动调用它 。 如果没有自动调用,请确保已经设置了地图视图的delegate属性(例如self )。

其次 (也是真正的问题)是,代码假定viewForAnnotation委托方法只会在添加每个注释后立即调用一次。

情况并非如此,也不能保证。 当需要显示注释时,地图视图将调用viewForAnnotation ,并且可以多次调用相同的注释,或者在注释实际添加之后(例如在用户平移或缩放地图并且注释进入视图之后)多次调用。

请参阅MKAnnotationView缓冲其input队列? 以获取更多详细信息以及其他答案的相关链接,包括示例代码。

基本上,您必须使用注释对象本身存储影响注释视图的属性,并从传入viewForAnnotationannotation参数中检索这些属性。

我build议你的情况是这样的:

我假设你正在使用内置的注释类MKPointAnnotation 。 而不是使用MKPointAnnotation ,它不会让您将自定义status属性与注释对象本身一起存储:

  • 创build一个实现MKAnnotation协议,但也有一个status属性的自定义类。 在创build注释时设置此属性,并从传入viewForAnnotationannotation参数中提取其值,并相应地设置pinColor 。 请参阅链接答案中的示例代码。

  • 使MySupplierData对象自己实现MKAnnotation协议的对象。 因此,如果MySupplierData中的对象是一些名为Supplier类的实例,请使Supplier类符合MKAnnotation协议,然后在调用addAnnotation时将MySupplierData对象本身添加到地图视图中。