简体   繁体   中英

Lots of problems with Map Annotations

I have several problems with what should be an amazingly simple piece of code. The goal is to read items from a database and make them pins in a map. The pin should be a different color if the item has been flagged as a favorite.

The very first problem is that not all the items are being rendered. In the example I will use there are 12 results returned from the query and I have verified that each item gets an MKAnnotation created and each annotation gets a call to ViewFor.

In addition to not displaying all the pins there are two other problems.

First Pins randomly lose their title when scrolling the map.

Second The favorite (green tint) is seldom rendered green. 80% of the time it comes out in the standard blue. Once again I have verified that the MKMarkerAnnotationView color is set correctly.

With all these problems I am forced to conclude I am doing something fundamentally very wrong. Which is strange because this seems dead simple.

class FacilityMarker: NSObject, MKAnnotation {

// title and subtitle are from the MKAnnotation protocol
var coordinate:     CLLocationCoordinate2D
var title:          String?
var address:        String
var phone:          String
var providerNumber: String
var favorite:       Bool
var subtitle:       String? {
    get {
        return phone
    }
}

View Controller

    class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {

@IBOutlet weak var mapView: MKMapView!

override func viewDidLoad() {
    super.viewDidLoad()
    mapView.delegate = self
    mapView.showAnnotations(mapView.annotations, animated: true)


// Create Annotations for all the facilities that are now visible on map
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    let edgePoints = mapView.edgePoints()

    let minLat = edgePoints.ne.latitude < edgePoints.sw.latitude ? edgePoints.ne.latitude : edgePoints.sw.latitude
    let maxLat = edgePoints.ne.latitude > edgePoints.sw.latitude ? edgePoints.ne.latitude : edgePoints.sw.latitude
    let minLong = edgePoints.ne.longitude < edgePoints.sw.longitude ? edgePoints.ne.longitude : edgePoints.sw.longitude
    let maxLong = edgePoints.ne.longitude > edgePoints.sw.longitude ? edgePoints.ne.longitude : edgePoints.sw.longitude
    let visibleCitiesReqeuest =
        managedObjectModel.fetchRequestFromTemplate(withName: "FetchByCoordinates", substitutionVariables: ["minLat" : minLat, "minLong" : minLong, "maxLat" : maxLat, "maxLong" : maxLong])
    do {
        let facilities = try CoreDataHelper.shared.persistentContainer.viewContext.fetch(visibleCitiesReqeuest!) as! [FacilityMO]
       for facility in facilities {
            let facilityMarker = FacilityMarker(name: facility.facilityName!, address: facility.addressLine1!, location: facility.location!, phone: facility.phoneNumber!, providerNumber: facility.providerNumber!, favorite: facility.favorite)   
            mapView.addAnnotation(facilityMarker)
        }
    } catch {
        let alertController = UIAlertController(title: "No Facilities", message: "There are no Facilities within the visible map area", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
        self.present(alertController, animated: true, completion: nil)
    }
}

// Put the pins in the map
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    guard let annotation = annotation as? FacilityMarker else { return nil}

    let identifier = "facility"
    var view: MKMarkerAnnotationView
    if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as?
        MKMarkerAnnotationView {
        dequeuedView.annotation = annotation
        view = dequeuedView
    } else {
        print("CREATING NEW View for: \(annotation.title!)")
        view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
    }

    // Set the Colors
    if (annotation.favorite) {
        view.markerTintColor = .green
        view.tintColor = .green
    } else {
        view.markerTintColor = .blue
        view.tintColor = .blue
    }
    return view
}

This is the actual data returned by the query. Only highlighted items are ever rendered. This is 100% consistent across all tests.

  • CREATING NEW View for: SEMINOLE DIALYSIS CENTER

  • CREATING NEW View for: LAKE SEMINOLE DIALYSIS
  • CREATING NEW View for: RAI CARE CENTERS - LARGO

  • CREATING NEW View for: BAY BREEZE DIALYSIS CLINIC INC

  • CREATING NEW View for: RENVIVA DIALYSIS CENTER OF CLEARWATER, LLC
  • CREATING NEW View for: FKC - BELLEAIR DIALYSIS CENTER

  • CREATING NEW View for: RAI CARE CENTERS - CLEARWATER

  • CREATING NEW View for: FMC - BELLEAIR HOME THERAPIES
  • CREATING NEW View for: CORVA GULF COAST DIALYSIS CENTER

  • CREATING NEW View for: GULF BREEZE DIALYSIS CENTER
  • CREATING NEW View for: BMA - CLEARWATER

  • CREATING NEW View for: RAI-US 19 NORTH-CLEARWATER

The following are captures showing the results described above

This is an initial render. This time the BMA pin is blue, it was set to Green. 初始渲染视图着色错误

After scrolling this time the BMA tint is correct. There is no pattern to when it will be right. 有时色调可以。可能在初始渲染中,也可能在滚动之后。未检测到图案

More scrolling and just to add more strangeness sometimes one or more annotations will not render their title attribute 有时滚动后注释标题会消失

The output from the requested debugging:

  • RAI CARE CENTERS - LARGO is blue
  • BMA - CLEARWATER is green
  • RENVIVA DIALYSIS CENTER OF CLEARWATER, LLC is blue
  • RAI CARE CENTERS - CLEARWATER is blue
  • FKC - BELLEAIR DIALYSIS CENTER is blue
  • FMC - BELLEAIR HOME THERAPIES is blue
  • GULF BREEZE DIALYSIS CENTER is blue
  • BAY BREEZE DIALYSIS CLINIC INC is blue
  • RAI-US 19 NORTH-CLEARWATER is blue
  • CORVA GULF COAST DIALYSIS CENTER is blue

Try the following debug code. Can you show the output?

    ...
    // Set the Colors
    if (annotation.favorite) {
        print(annotation.title, "is green")
        view.markerTintColor = .green
        view.tintColor = .green
    } else {
        print(annotation.title, "is blue")
        view.markerTintColor = .blue
        view.tintColor = .blue
    }
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM