目标是根据存储在结构数组中的某些值自定义引脚颜色。
根据这里的一些帮助,我实现了以下viewForAnnotation委托方法,并且可以在基于结构数据数组大小的循环中迭代地调用此委托方法。因此,如果我想将所有引脚设置为一种颜色,例如紫色(这是下面代码中的注释行),它就可以工作。
问题是,当我根据数组中的值设置颜色时,它会通过此代码,但不会考虑任何案例值将其设置为备用颜色,并且所有内容都变为红色pin(看似默认)。我打印出状态并进行了调试,知道它已经进入开关并相应地设置了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根据Anna的大力帮助/辅导解决修改后代码问题的更新。 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
Debug输出显示For循环执行完成按预期在mapView中自定义viewForAnnotation获取之前创建myCustomPinAnnotation 在内部执行。当我将地图移动到直接视图之外的区域时,我注意到mapView中的viewForAnnotation会根据需要进行调用 并且我看到我的开关相应地执行但是引脚颜色并不总是正确的。每次初始显示图中的所有引脚都是正确的 这是我目前所关注的那些外围区域的原因。
答案 0 :(得分:9)
首先,代码应 自行调用viewForAnnotation
。
在viewForAnnotation
行后删除对addAnnotation
的显式调用。
viewForAnnotation
是一种委托方法,地图视图会在需要显示注释时自动调用。如果没有自动调用,请确保已设置地图视图的delegate
属性(例如,设置为self
。)
第二(以及真正的问题)是代码假定viewForAnnotation
委托方法只会在添加每个注释后立即调用一次。
情况并非如此,并不能保证。地图视图将在需要显示注释时调用viewForAnnotation
,并且可以针对相同注释多次调用,或者在实际添加注释之后很久(例如,在用户平移或缩放地图并且注释进入之后)视图)。
有关其他答案的一些其他详细信息和相关链接,请参阅does MKAnnotationView buffer its input queue?。
基本上,您必须使用注释对象本身存储影响注释视图的属性,并从传递到annotation
的{{1}}参数中检索这些属性。
我建议您使用的是:
我假设您使用的是内置注释类viewForAnnotation
。而不是使用MKPointAnnotation
不允许您将自定义MKPointAnnotation
属性与注释对象本身一起存储,而是:
创建一个实现status
协议但具有MKAnnotation
属性的自定义类。在创建注释时设置此属性,并从传递到status
的{{1}}参数中提取其值,并相应地设置annotation
。请参阅链接答案中的示例代码。
在实现viewForAnnotation
协议的pinColor
自身对象中创建对象。因此,如果MySupplierData
中的对象是名为MKAnnotation
的某个类的实例,请使MySupplierData
类符合Supplier
协议,然后您可以添加{{ 1}}在调用Supplier
时将对象自身对齐到地图视图。