将数据从查询传递到 mapView viewForAnnotation 函数
Passing data from a query to mapView viewForAnnotation function
我正在尝试在 MKMapView 上显示自定义图钉。这些图钉将具有自定义图像以及将显示值的 UILabel。
我能够成功创建带有标签的自定义图钉。现在标签显示静态值。我从像解析这样的后端服务中查询数据,并为每个点保存数据。这样,当用户点击某个点时,我可以在 viewController
中显示数据,但是我不确定如何将这些数据从我的查询方法传递到 didSelectAnnotation 和 viewForAnnotation 方法。
我还想将标签显示的静态值更改为从服务器查询的值。我试图通过创建一个名为 CustomPointAnnotation
的 class 来做到这一点,它继承自 MKPointAnnotation
并具有一个具有三个属性的初始化程序。这些属性是在查询期间设置的,所以我如何在 mapViewDidSelectAnnotationView
和 viewForAnnotation
函数中访问这些属性,以便我可以根据需要使用数据。 (对于诸如将 viewController
中的标签文本设置为该特定注释的 属性 之类的事情)。
下图显示了 viewController 以及我目前拥有的内容:
这里是自定义点class:
class CustomPointAnnotation: MKPointAnnotation {
var price: String!
var streetName: String!
var ratingValue: Int!
init?(price: String, streetName: String, ratingValue: Int) {
self.price = price
self.streetName = streetName
self.ratingValue = ratingValue
super.init()
}
}
下面是我在 viewDidLoad 中 运行 的查询:
func displayPoints() {
let pointsQuery = PFQuery(className: "testLocation")
let currentLocation = PFGeoPoint(location: locationManager.location)
pointsQuery.whereKey("location", nearGeoPoint: currentLocation, withinMiles: 2)
pointsQuery.findObjectsInBackgroundWithBlock { (points, error) -> Void in
if error == nil {
print("number of spots: \(points?.count)")
let spots = points! as [PFObject]
for pinPoint in spots {
let point = pinPoint["location"] as! PFGeoPoint
let price = String(pinPoint["price"])
let ratingValue = pinPoint["rating"] as! Int
let streetName = "Park Street, San Francisco CA"
self.customAnnotation = CustomPointAnnotation(price: price, streetName: streetName, ratingValue: ratingValue)
//// PRINT DATA OBTAINED FOR TESTING PURPOSES///////////////////////////////////////////////////////////
print(self.customAnnotation.price)
print(self.customAnnotation.streetName)
print(self.customAnnotation.ratingValue)
///////////////////////////////////////////////////////////////////////////////////////////////////////
self.customAnnotation!.coordinate = CLLocationCoordinate2DMake(point.latitude, point.longitude)
self.priceArray.append(pinPoint["price"])
self.customAnnotation!.price = pinPoint["price"] as? String
self.mapView.addAnnotation(self.customAnnotation!)
}
} else {
JSSAlertView().danger(self, title: "something went wrong", text: "error: \(error)")
}
}
}
这里是 didSelectAnnotationView:
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//var anot: MKAnnotation
if ((view.annotation?.isKindOfClass(MKUserLocation)) != nil){
view.image = nil
}
for anot in mapView.annotations {
print(mapView.annotations.count)
let annotationView = mapView.viewForAnnotation(anot)
if (annotationView != nil) {
annotationView?.image = UIImage(named: "pin")
priceLabel.textColor = UIColor.whiteColor()
}
//priceLabel.textColor = UIColor.blueColor()
view.image = UIImage(named: "pinselected")
print("image changed")
}
}
最后是 viewForAnnotation 方法:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(MKUserLocation){
return nil
}
if !(annotation is CustomPointAnnotation) {
print("all custom images added")
return nil
}
let reuseID = "identifier"
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID)
if annotationView == nil {
annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: reuseID, price: "13" )
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = annotation
}
//let cpa = annotation as! CustomPointAnnotation
//let annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: nil, price: "11")
//annotationView!.addSubview(priceLabel)
annotationView?.annotation = annotation
annotationView?.image = UIImage(named: "pin.png")
return annotationView
}
您可以使用 as 运算符在 swift 中进行向下转换。在 didSelectAnnotationView 中,annotationView 有一个注解 属性。您的自定义注释视图会将您的自定义注释作为其注释 属性,因此您可以通过以下方式尝试将其向下转换为您的子类:
if let annotation = view.annotation as? CustomPointAnnotation
假设这是可能的,那么您将可以访问子类的属性。
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//var anot: MKAnnotation
if ((view.annotation?.isKindOfClass(MKUserLocation)) != nil){
view.image = nil
}
for anot in mapView.annotations {
print(mapView.annotations.count)
let annotationView = mapView.viewForAnnotation(anot)
if (annotationView != nil) {
annotationView?.image = UIImage(named: "pin")
priceLabel.textColor = UIColor.whiteColor()
}
//priceLabel.textColor = UIColor.blueColor()
}
view.image = UIImage(named: "pinselected")
if let annotation = view.annotation as? CustomPointAnnotation
{
self.priceLabel.text = annotation.price //for example
//update the rest of your UI
}
print("image changed")
}
与 viewForAnnotation 类似,您可以将 MKAnnotation 向下转换为 CustomPointAnnotation,将 MKAnnotationView 向下转换为 CustomAnnotationView。
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(MKUserLocation){
return nil
}
if !(annotation is CustomPointAnnotation) {
print("all custom images added")
return nil
}
let reuseID = "identifier"
let cpa = annotation as! CustomPointAnnotation
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID) as! CustomAnnotationView
if annotationView == nil {
annotationView = CustomAnnotationView(annotation: cpa, reuseIdentifier: reuseID, price: cpa.price)
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = cpa
annotationView?.price = cpa.price
}
annotationView?.image = UIImage(named: "pin.png")
return annotationView
}
您的 CustomAnnotationView 应在通过实施价格的 didSet 设置价格时更新其价格标签。
我正在尝试在 MKMapView 上显示自定义图钉。这些图钉将具有自定义图像以及将显示值的 UILabel。
我能够成功创建带有标签的自定义图钉。现在标签显示静态值。我从像解析这样的后端服务中查询数据,并为每个点保存数据。这样,当用户点击某个点时,我可以在 viewController
中显示数据,但是我不确定如何将这些数据从我的查询方法传递到 didSelectAnnotation 和 viewForAnnotation 方法。
我还想将标签显示的静态值更改为从服务器查询的值。我试图通过创建一个名为 CustomPointAnnotation
的 class 来做到这一点,它继承自 MKPointAnnotation
并具有一个具有三个属性的初始化程序。这些属性是在查询期间设置的,所以我如何在 mapViewDidSelectAnnotationView
和 viewForAnnotation
函数中访问这些属性,以便我可以根据需要使用数据。 (对于诸如将 viewController
中的标签文本设置为该特定注释的 属性 之类的事情)。
下图显示了 viewController 以及我目前拥有的内容:
这里是自定义点class:
class CustomPointAnnotation: MKPointAnnotation {
var price: String!
var streetName: String!
var ratingValue: Int!
init?(price: String, streetName: String, ratingValue: Int) {
self.price = price
self.streetName = streetName
self.ratingValue = ratingValue
super.init()
}
}
下面是我在 viewDidLoad 中 运行 的查询:
func displayPoints() {
let pointsQuery = PFQuery(className: "testLocation")
let currentLocation = PFGeoPoint(location: locationManager.location)
pointsQuery.whereKey("location", nearGeoPoint: currentLocation, withinMiles: 2)
pointsQuery.findObjectsInBackgroundWithBlock { (points, error) -> Void in
if error == nil {
print("number of spots: \(points?.count)")
let spots = points! as [PFObject]
for pinPoint in spots {
let point = pinPoint["location"] as! PFGeoPoint
let price = String(pinPoint["price"])
let ratingValue = pinPoint["rating"] as! Int
let streetName = "Park Street, San Francisco CA"
self.customAnnotation = CustomPointAnnotation(price: price, streetName: streetName, ratingValue: ratingValue)
//// PRINT DATA OBTAINED FOR TESTING PURPOSES///////////////////////////////////////////////////////////
print(self.customAnnotation.price)
print(self.customAnnotation.streetName)
print(self.customAnnotation.ratingValue)
///////////////////////////////////////////////////////////////////////////////////////////////////////
self.customAnnotation!.coordinate = CLLocationCoordinate2DMake(point.latitude, point.longitude)
self.priceArray.append(pinPoint["price"])
self.customAnnotation!.price = pinPoint["price"] as? String
self.mapView.addAnnotation(self.customAnnotation!)
}
} else {
JSSAlertView().danger(self, title: "something went wrong", text: "error: \(error)")
}
}
}
这里是 didSelectAnnotationView:
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//var anot: MKAnnotation
if ((view.annotation?.isKindOfClass(MKUserLocation)) != nil){
view.image = nil
}
for anot in mapView.annotations {
print(mapView.annotations.count)
let annotationView = mapView.viewForAnnotation(anot)
if (annotationView != nil) {
annotationView?.image = UIImage(named: "pin")
priceLabel.textColor = UIColor.whiteColor()
}
//priceLabel.textColor = UIColor.blueColor()
view.image = UIImage(named: "pinselected")
print("image changed")
}
}
最后是 viewForAnnotation 方法:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(MKUserLocation){
return nil
}
if !(annotation is CustomPointAnnotation) {
print("all custom images added")
return nil
}
let reuseID = "identifier"
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID)
if annotationView == nil {
annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: reuseID, price: "13" )
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = annotation
}
//let cpa = annotation as! CustomPointAnnotation
//let annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: nil, price: "11")
//annotationView!.addSubview(priceLabel)
annotationView?.annotation = annotation
annotationView?.image = UIImage(named: "pin.png")
return annotationView
}
您可以使用 as 运算符在 swift 中进行向下转换。在 didSelectAnnotationView 中,annotationView 有一个注解 属性。您的自定义注释视图会将您的自定义注释作为其注释 属性,因此您可以通过以下方式尝试将其向下转换为您的子类:
if let annotation = view.annotation as? CustomPointAnnotation
假设这是可能的,那么您将可以访问子类的属性。
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//var anot: MKAnnotation
if ((view.annotation?.isKindOfClass(MKUserLocation)) != nil){
view.image = nil
}
for anot in mapView.annotations {
print(mapView.annotations.count)
let annotationView = mapView.viewForAnnotation(anot)
if (annotationView != nil) {
annotationView?.image = UIImage(named: "pin")
priceLabel.textColor = UIColor.whiteColor()
}
//priceLabel.textColor = UIColor.blueColor()
}
view.image = UIImage(named: "pinselected")
if let annotation = view.annotation as? CustomPointAnnotation
{
self.priceLabel.text = annotation.price //for example
//update the rest of your UI
}
print("image changed")
}
与 viewForAnnotation 类似,您可以将 MKAnnotation 向下转换为 CustomPointAnnotation,将 MKAnnotationView 向下转换为 CustomAnnotationView。
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(MKUserLocation){
return nil
}
if !(annotation is CustomPointAnnotation) {
print("all custom images added")
return nil
}
let reuseID = "identifier"
let cpa = annotation as! CustomPointAnnotation
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID) as! CustomAnnotationView
if annotationView == nil {
annotationView = CustomAnnotationView(annotation: cpa, reuseIdentifier: reuseID, price: cpa.price)
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = cpa
annotationView?.price = cpa.price
}
annotationView?.image = UIImage(named: "pin.png")
return annotationView
}
您的 CustomAnnotationView 应在通过实施价格的 didSet 设置价格时更新其价格标签。