如何在地图视图中创建多个自定义注释?
How can I create multiple custom annotations in a map view?
这个想法很简单。我有一个 StopData() 数组,这是我创建的自定义结构,通过为每个循环执行一个 mapView 来显示不同的位置。我的代码看起来有点像这样:
var route = [StopData]()
struct StopData {
var addr: String?
var coord: CLLocationCoordinate2D?
var number: Int?
var completed = false
}
func addStopsToMap() {
mapView.removeAnnotations(mapView.annotations)
for stop in route {
let annotation = MKPointAnnotation()
annotation.coordinate = stop.coord!
annotation.title = "\(stop.number!)"
annotation.subtitle = stop.addr
mapView.addAnnotation(annotation)
}
}
func attemptLocationAccess() {
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation")
}
// MARK: - Location manager functions
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
return
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else {
return
}
manager.requestLocation()
}
我也有一个自定义 class,如下所示:
class NonClusteringAnnotation: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
displayPriority = .required
}
}
}
我想完成三件主要的事情。
- 显示每个注释图钉,但不要将其聚类
- 如果完成的变量为 false,则显示自定义注释
- 如果完成为真,则显示不同的自定义注释
使用此代码,每个图钉都显示在地图上并且不会聚集。然而,这也包括当前位置蓝点,它像所有注释的其余部分一样显示为红色图钉。所以我想知道如何制作多个自定义注释视图并只为它们分配某些注释,同时仍然保留指示用户当前位置的蓝点?
到目前为止我尝试的是添加一个布尔变量,如 willUseCustomAnnotation,它会触发不同的 return 值,如下所示:
func addStopsToMap() {
mapView.removeAnnotations(mapView.annotations)
willUseCustomAnnotation = true
for stop in route {
let annotation = MKPointAnnotation()
annotation.coordinate = stop.coord!
annotation.title = "\(stop.number!)"
annotation.subtitle = stop.addr
mapView.addAnnotation(annotation)
}
willUseCustomAnnotation = false
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if willUseCustomAnnotation {
return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation")
} else {
return nil
}
}
虽然这不起作用,因为我认为它首先将所有注释添加到 mapview,然后同时为它们创建视图。
我在论坛上读到要更改注释的视图,您必须在 viewForAnnotation 函数中创建自己的视图,但这仅适用于您想要单个自定义视图而不是我想要的多个自定义视图的情况。我是 MapKit 的新手,所以非常感谢帮助。
我已经很久没有使用 MKMapView 和自定义注释了(它在 Objective-C。)
我似乎记得在您的 mapView(_:viewFor:)
函数中您需要测试以查看传递给您的注释是否是 MKUserLocation。如果是,return nil:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !annotation is MKUserLocation else {
//This is the user location. Return nil so the system uses the blue dot.
return nil
}
//Your code to create an return custom annotations)
}
这个想法很简单。我有一个 StopData() 数组,这是我创建的自定义结构,通过为每个循环执行一个 mapView 来显示不同的位置。我的代码看起来有点像这样:
var route = [StopData]()
struct StopData {
var addr: String?
var coord: CLLocationCoordinate2D?
var number: Int?
var completed = false
}
func addStopsToMap() {
mapView.removeAnnotations(mapView.annotations)
for stop in route {
let annotation = MKPointAnnotation()
annotation.coordinate = stop.coord!
annotation.title = "\(stop.number!)"
annotation.subtitle = stop.addr
mapView.addAnnotation(annotation)
}
}
func attemptLocationAccess() {
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation")
}
// MARK: - Location manager functions
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
return
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.requestWhenInUseAuthorization()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else {
return
}
manager.requestLocation()
}
我也有一个自定义 class,如下所示:
class NonClusteringAnnotation: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
displayPriority = .required
}
}
}
我想完成三件主要的事情。
- 显示每个注释图钉,但不要将其聚类
- 如果完成的变量为 false,则显示自定义注释
- 如果完成为真,则显示不同的自定义注释
使用此代码,每个图钉都显示在地图上并且不会聚集。然而,这也包括当前位置蓝点,它像所有注释的其余部分一样显示为红色图钉。所以我想知道如何制作多个自定义注释视图并只为它们分配某些注释,同时仍然保留指示用户当前位置的蓝点?
到目前为止我尝试的是添加一个布尔变量,如 willUseCustomAnnotation,它会触发不同的 return 值,如下所示:
func addStopsToMap() {
mapView.removeAnnotations(mapView.annotations)
willUseCustomAnnotation = true
for stop in route {
let annotation = MKPointAnnotation()
annotation.coordinate = stop.coord!
annotation.title = "\(stop.number!)"
annotation.subtitle = stop.addr
mapView.addAnnotation(annotation)
}
willUseCustomAnnotation = false
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if willUseCustomAnnotation {
return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation")
} else {
return nil
}
}
虽然这不起作用,因为我认为它首先将所有注释添加到 mapview,然后同时为它们创建视图。
我在论坛上读到要更改注释的视图,您必须在 viewForAnnotation 函数中创建自己的视图,但这仅适用于您想要单个自定义视图而不是我想要的多个自定义视图的情况。我是 MapKit 的新手,所以非常感谢帮助。
我已经很久没有使用 MKMapView 和自定义注释了(它在 Objective-C。)
我似乎记得在您的 mapView(_:viewFor:)
函数中您需要测试以查看传递给您的注释是否是 MKUserLocation。如果是,return nil:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !annotation is MKUserLocation else {
//This is the user location. Return nil so the system uses the blue dot.
return nil
}
//Your code to create an return custom annotations)
}