【问题标题】:How can I create multiple custom annotations in a map view?如何在地图视图中创建多个自定义注释?
【发布时间】:2020-09-03 22:22:52
【问题描述】:

这个想法很简单。我有一个 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 NonClusteringAnnotation: MKMarkerAnnotationView {
    override var annotation: MKAnnotation? {
        willSet {
            displayPriority = .required
        }
    }
}

我想完成三件主要的事情。

  • 显示每个注释图钉,而不是使其成簇
  • 如果完成的变量为假,则显示自定义注释
  • 如果完成为真,则显示不同的自定义注释

使用此代码,每个图钉都显示在地图上并且不会聚集。但是,这也包括当前位置的蓝点,它像所有注释的其余部分一样显示为红色图钉。所以我想知道如何制作多个自定义注释视图并仅为其分配某些注释,同时仍保留指示用户当前位置的蓝点?

到目前为止,我尝试的是添加一个布尔变量,例如 willUseCustomAnnotation,它会触发不同的返回值,如下所示:

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 新手,非常感谢您的帮助。

【问题讨论】:

    标签: swift xcode mkmapview mkannotation mkannotationview


    【解决方案1】:

    我已经很久没有使用 MKMapView 和自定义注释了(它是在 Objective-C 中的。)

    我似乎记得在您的mapView(_:viewFor:) 函数中,您需要测试以查看传递给您的注释是否是 MKUserLocation。如果是,则返回 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)
    }
    

    【讨论】:

    • if annotation === mapView.userLocation { return nil } else { return NonClusteringAnnotation(annotation: annotation, reuseIdentifier: "NonClusteringAnnotation") } 我将此添加到我的 viewForAnnotation 中,我的蓝点再次出现!无论如何我可以检查是否已完成是 = 为真然后我显示不同的标记?
    • 你的代码也可以。至于检查是否completed == true,应该很容易。但是,我不清楚您的结构是如何创建/修改的。结构是值对象,所以任何时候你试图传递它,你都会得到一个新的副本而不是原来的。您必须解释更多代码,以及为什么在这种情况下使用结构。
    • 基本上,我有一个名为 GlobalVariables.swift 的文件,其中包含此结构,以便其他视图控制器可以读取和修改它。每当修改结构时,我都会调用一个函数来刷新屏幕addStopsToMap(),其中包括删除地图上的所有注释并使用更新的数据读取它们。所以我没有传递结构,而是使用 for 循环读取它。在viewForAnnotation 中,我看不到任何方法可以检查该注释的stopData 是否标记为true 如果您需要更多信息,请告诉我
    猜你喜欢
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多