Swift MKMapView Pin 注释问题
Swift MKMapView Pin Annotation Issue
我正在尝试使用预设搜索参数在地图上显示图钉。单击按钮,该应用程序会显示所有本地出租车服务。那部分我记下来了...我将项目附加到 [MKPointAnnotation]
,它成功地在 tableView
中显示了一个填充列表以及 mapView
中的图钉。出于某种原因,即使在实现 viewFor annotation:
委托时,当您点击 mapView
上的图钉时,我也无法显示标题和副标题。有什么想法吗?
class MapViewController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource, UITableViewDelegate, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var tableView: UITableView!
let locationManager = CLLocationManager()
let regionRadius: CLLocationDistance = 1500
var matchingItems: [MKMapItem] = [MKMapItem]()
var annotationGroup = [MKPointAnnotation]()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
tableView.delegate = self
tableView.dataSource = self
mapView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.allowsSelection = true
let currentLocation = locationManager.location
guard let latitude = currentLocation?.coordinate.latitude,
let longitude = currentLocation?.coordinate.longitude else {
alertPopup(title: "Enable Location Services", message: "Navigate to Settings >", buttonTitle: "Ok")
return
}
let initialLocation = CLLocation(latitude: latitude, longitude: longitude)
tabBarController?.tabBar.isHidden = true
centerMapOnLocation(location: initialLocation)
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "Taxi"
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.start(completionHandler: {(response, error) in
if error != nil {
print("Error occured in search: \(error!.localizedDescription)")
} else if response!.mapItems.count == 0 {
print("No Matches Found")
} else {
print("Matches Found")
}
for location in response!.mapItems {
print("Name = \(String(describing: item.name))")
print("Phone = \(String(describing: item.phoneNumber))")
self.matchingItems.append(item)
var pinAnnotationView = MKPinAnnotationView()
let annotation = MKPointAnnotation()
annotation.coordinate.longitude = location.placemark.coordinate.longitude
annotation.coordinate.latitude = location.placemark.coordinate.latitude
annotation.title? = location.name!
annotation.subtitle = location.phoneNumber!
self.annotationGroup.append(annotation)
self.mapView.addAnnotations(self.annotationGroup)
pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
self.mapView.addAnnotation(pinAnnotationView.annotation!)
}
self.tableView.reloadData()
print("Reloaded Table Data")
print(self.matchingItems)
self.mapView.showAnnotations(self.annotationGroup, animated: true)
})
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is MKUserLocation) {
let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))
let rightButton = UIButton(type: .contactAdd)
rightButton.tag = annotation.hash
pinView.animatesDrop = true
pinView.canShowCallout = true
pinView.rightCalloutAccessoryView = rightButton
return pinView
} else {
print("Returned nil")
return nil
}
}
}
问题是可选的 annotation.title? = location.name!
。删除可选的并且它有效。
for location in response!.mapItems {
print("Name = \(String(describing: location.name))")
print("Phone = \(String(describing: location.phoneNumber))")
self.matchingItems.append(location)
let annotation = MKPointAnnotation()
annotation.coordinate.longitude = location.placemark.coordinate.longitude
annotation.coordinate.latitude = location.placemark.coordinate.latitude
annotation.title = location.name! //This is the line to remove the optional annotation.title? from.
annotation.subtitle = location.phoneNumber!
self.annotationGroup.append(annotation)
self.mapView.addAnnotations(self.annotationGroup)
self.mapView.showAnnotations(self.annotationGroup, animated: true)
}
也许为时已晚但无论如何
首先,MKAnnotation
是一个协议,所以我认为你必须为你的对象定义一个自定义 class,并且这个 class 必须实现这个协议,或者在这种情况下我们可以为 MKMapItem
定义一个扩展,实现 MKAnnotation
协议
extension MKMapItem : MKAnnotation
{
public var coordinate: CLLocationCoordinate2D {
return self.placemark.coordinate
}
// Title and subtitle for use by selection UI.
public var title: String? {
return self.name
}
public var subtitle: String? {
return self.phoneNumber
}
}
有了这个你的代码将减少到这个
search.start(completionHandler: {(response, error) in
if error != nil {
print("Error occured in search: \(error!.localizedDescription)")
} else if response!.mapItems.count == 0 {
print("No Matches Found")
} else {
print("Matches Found")
}
for location in response!.mapItems {
print("Name = \(String(describing: item.name))")
print("Phone = \(String(describing: item.phoneNumber))")
self.matchingItems.append(item)
}
self.mapView.addAnnotations(self.matchingItems)
self.tableView.reloadData()
print("Reloaded Table Data")
print(self.matchingItems)
self.mapView.showAnnotations(self.matchingItems, animated: true)
})
一旦你有了这个,那么你的 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {}
的实现应该可以工作了
希望对您有所帮助
我正在尝试使用预设搜索参数在地图上显示图钉。单击按钮,该应用程序会显示所有本地出租车服务。那部分我记下来了...我将项目附加到 [MKPointAnnotation]
,它成功地在 tableView
中显示了一个填充列表以及 mapView
中的图钉。出于某种原因,即使在实现 viewFor annotation:
委托时,当您点击 mapView
上的图钉时,我也无法显示标题和副标题。有什么想法吗?
class MapViewController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource, UITableViewDelegate, MKMapViewDelegate {
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var tableView: UITableView!
let locationManager = CLLocationManager()
let regionRadius: CLLocationDistance = 1500
var matchingItems: [MKMapItem] = [MKMapItem]()
var annotationGroup = [MKPointAnnotation]()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
tableView.delegate = self
tableView.dataSource = self
mapView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.allowsSelection = true
let currentLocation = locationManager.location
guard let latitude = currentLocation?.coordinate.latitude,
let longitude = currentLocation?.coordinate.longitude else {
alertPopup(title: "Enable Location Services", message: "Navigate to Settings >", buttonTitle: "Ok")
return
}
let initialLocation = CLLocation(latitude: latitude, longitude: longitude)
tabBarController?.tabBar.isHidden = true
centerMapOnLocation(location: initialLocation)
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = "Taxi"
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.start(completionHandler: {(response, error) in
if error != nil {
print("Error occured in search: \(error!.localizedDescription)")
} else if response!.mapItems.count == 0 {
print("No Matches Found")
} else {
print("Matches Found")
}
for location in response!.mapItems {
print("Name = \(String(describing: item.name))")
print("Phone = \(String(describing: item.phoneNumber))")
self.matchingItems.append(item)
var pinAnnotationView = MKPinAnnotationView()
let annotation = MKPointAnnotation()
annotation.coordinate.longitude = location.placemark.coordinate.longitude
annotation.coordinate.latitude = location.placemark.coordinate.latitude
annotation.title? = location.name!
annotation.subtitle = location.phoneNumber!
self.annotationGroup.append(annotation)
self.mapView.addAnnotations(self.annotationGroup)
pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
self.mapView.addAnnotation(pinAnnotationView.annotation!)
}
self.tableView.reloadData()
print("Reloaded Table Data")
print(self.matchingItems)
self.mapView.showAnnotations(self.annotationGroup, animated: true)
})
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is MKUserLocation) {
let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))
let rightButton = UIButton(type: .contactAdd)
rightButton.tag = annotation.hash
pinView.animatesDrop = true
pinView.canShowCallout = true
pinView.rightCalloutAccessoryView = rightButton
return pinView
} else {
print("Returned nil")
return nil
}
}
}
问题是可选的 annotation.title? = location.name!
。删除可选的并且它有效。
for location in response!.mapItems {
print("Name = \(String(describing: location.name))")
print("Phone = \(String(describing: location.phoneNumber))")
self.matchingItems.append(location)
let annotation = MKPointAnnotation()
annotation.coordinate.longitude = location.placemark.coordinate.longitude
annotation.coordinate.latitude = location.placemark.coordinate.latitude
annotation.title = location.name! //This is the line to remove the optional annotation.title? from.
annotation.subtitle = location.phoneNumber!
self.annotationGroup.append(annotation)
self.mapView.addAnnotations(self.annotationGroup)
self.mapView.showAnnotations(self.annotationGroup, animated: true)
}
也许为时已晚但无论如何
首先,MKAnnotation
是一个协议,所以我认为你必须为你的对象定义一个自定义 class,并且这个 class 必须实现这个协议,或者在这种情况下我们可以为 MKMapItem
定义一个扩展,实现 MKAnnotation
协议
extension MKMapItem : MKAnnotation
{
public var coordinate: CLLocationCoordinate2D {
return self.placemark.coordinate
}
// Title and subtitle for use by selection UI.
public var title: String? {
return self.name
}
public var subtitle: String? {
return self.phoneNumber
}
}
有了这个你的代码将减少到这个
search.start(completionHandler: {(response, error) in
if error != nil {
print("Error occured in search: \(error!.localizedDescription)")
} else if response!.mapItems.count == 0 {
print("No Matches Found")
} else {
print("Matches Found")
}
for location in response!.mapItems {
print("Name = \(String(describing: item.name))")
print("Phone = \(String(describing: item.phoneNumber))")
self.matchingItems.append(item)
}
self.mapView.addAnnotations(self.matchingItems)
self.tableView.reloadData()
print("Reloaded Table Data")
print(self.matchingItems)
self.mapView.showAnnotations(self.matchingItems, animated: true)
})
一旦你有了这个,那么你的 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {}
的实现应该可以工作了
希望对您有所帮助