2016-03-27 16 views
9

So che questa domanda è stata posta più volte, tuttavia tutte le risposte sembrano leggermente diverse rispetto a ciò che accade nella mia app.Perché ViewForAnnotation non è stato chiamato?

La mia comprensione è che la funzione viewForAnnotation viene chiamata una volta che mapView ha il suo delegato impostato sul ViewController in cui viene visualizzato E un'annotazione viene aggiunta alla mappa quando mapView scorre in modo che venga visualizzato all'interno della regione mapView .

Attualmente ho una viewController principale (mainVC) che contiene una MKMapView (MapView) Questo viewController controlla quattro diverse mappe da visualizzare in MapView.

func moveViews(sender:Int) { 
    // This function handles which button on the Segmented Control was clicked and the loads the appropriate map into the mapView (passed as a para 

    removeAnnotationsAndOverlays() // ~~~ 
    if sender == 0 { 
     // First Map was selected 
     let map1VC = map1VC() 
     map1VC.loadMap1View(mapView) 
     map1VC.centerMapOnLocation() 
    } 
    else if sender == 1 { 
     // Second Map was selected 
     let map2VC = map2VC() 
     map2VC.loadMap2View(mapView) 
    } 
    else if sender == 2 { 
     // Third Map was selected 
     let map3VC = map3VC() 
     map3VC.loadMap3View(mapView) 
    } 
    else if sender == 3 { 
     // Fourth Map was selected 
     let map4VC = map4VC() 
     map4VC.loadMap4View(mapView) 
    } 
    else { 
     // Load First Map as default 
     let map1VC = map1VC() 
     map1VC.loadMap1View(mapView) 
     map1VC.centerMapOnLocation() 
    } 
} 

Ci sono diverse classi diverse, che controlla la funzionalità di ciascuna delle diverse mappe:

  1. Mappa 1 - Consente di visualizzare una combinazione di MKPolylines e annotazioni personalizzate (eredita da MKAnnotation) che vengono lette da un plist - Funziona alla grande!
  2. Mappa 2 - Visualizza diversi MKPolylines letti da un plist - Funziona benissimo!
  3. Mappa 3 - Visualizza diversi MKPolylines letti da un plist - Funziona benissimo!
  4. Mappa 4 - Dovrebbe visualizzare più annotazioni personalizzate - questo NON FUNZIONA!

Ecco che cosa sta accadendo con mappa 4:

  • il MKMapView viene caricata correttamente

    var mapView: MKMapView = MKMapView() // declared as a global variable/object inside the map4VC() 
    
    // Initial function to set up Map 
    //  Think of this function as the "override func viewDidLoad() {}" 
    func loadMap4View(mV: MKMapView) { 
    
    // This connects the parameter passed (mV) and sets it as the delegate for the mapView used throughout this file 
    //  In other words, it allows the mapView on the MainVC to use all of the code in this file to handle different actions 
    mapView = mV 
    mapView.delegate = self 
    
    let initialLocation = CLLocation(latitude: 50.3603125, longitude: 2.794017) 
    
    // calculates the region you'll look at on the screen 
    let coordinateRegion = MKCoordinateRegionMakeWithDistance(initialLocation.coordinate, regionRadius, regionRadius) 
    
    // sets the region of the map 
    mapView.setRegion(coordinateRegion, animated: true) 
    
    
    //addPins() // This can use a custom function to load all of the Pins 
    //mapView.addAnnotations(coords.allLocations!) // This line also works to add all of the individual pins 
    
    mapView.addAnnotation(coords.allLocations![2]) // This adds one single Pin 
    

    }

  • impostato delegato del MapView alla classe corrente (mapView.delegate = self)

  • si ingrandisce sulla posizione corretta (mapView.setRegion (coordinateRegion, animato: true))
  • la classe legge da un plist e (utilizzando una classe di supporto) costruisce una serie di MKAnnotations personalizzati (CemAnno)

  • Le posizioni sono memorizzate in una serie di chiamate di allLocations CemAnno:

    var allLocations: [CemAnno]? = [] // This is declared in the helper class along with a bunch of other stuff that grabs all of the information from a plist 
    
    class CemAnno: NSObject, MKAnnotation { 
    
    var coordinate: CLLocationCoordinate2D 
    var title: String? 
    var casualties: String? 
    var visitInfo: String? 
    var histInfo: String? 
    var region: String? 
    
    
    init(title: String, coordinate: CLLocationCoordinate2D, region: String, casualties: String, visitInfo: String, histInfo: String) { 
    
    self.coordinate = coordinate 
    self.title = title 
    self.region = region 
    self.casualties = casualties 
    self.visitInfo = visitInfo 
    self.histInfo = histInfo 
    } 
    

    }

    // This builds an object inside the the map4VC() class called coords that holds all of the information collected from the plist 
    var coords = BuildCoordinates(filename: "Coordinate") 
    
  • aggiunge eac h uno di questi alla mappa (mapView.addAnnotations) e vengono visualizzati come pin (vengono visualizzati) mapView.addAnnotation (coords.allLocations! [2]) // Questo aggiunge una singola Annotazione di Pin (che funziona) ma chiama mai la funzione viewForAnnotation

Questo funziona, però, sto cercando di personalizzare le annotazioni che vengono visualizzati, ma la funzione ViewForAnnotation non viene mai chiamato ????

// This function is NEVER called 
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? 
{ 
    // Define a reuse identifier. This is a string that will be used to ensure we reuse annotation views as much as possible. 
    let identifier = "CemAnno" 

    // Check whether the annotation we're creating a view for is one of our CemAnno objects. 
    if annotation.isKindOfClass(CemAnno.self) { 
     print("correct class") 
     //let anno = annotation as! CustomAnnotation 
     // Try to dequeue an annotation view from the map view's pool of unused views. 
     var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) 

     if annotationView == nil { 
      print("no reusable view") 
      // If it isn't able to find a reusable view, create a new one using MKPinAnnotationView and sets its canShowCallout property to be true. This triggers the popup with the name. 
      annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) 
      annotationView!.canShowCallout = true 

      // Create a new UIButton using the built-in .Custom type. This is so we can add an image to the button. 
      let btn = UIButton(type: .DetailDisclosure) 
      //btn.setImage(anno.image, forState: .Normal) 
      annotationView!.rightCalloutAccessoryView = btn 
     } else { 
      print("reusing a view") 
      // If it can reuse a view, update that view to use a different annotation. 
      annotationView!.annotation = annotation 
     } 

     return annotationView 

    } 

    // If the annotation isn't from a CustomClass, it must return nil so iOS uses a default view. 
    return MKPinAnnotationView() 
} 

Ho provato ad aggiungere la posizione di un perno all'interno della visualizzazione corrente zona della mappa, ma il ViewForAnnotation è mai sparato. Ho provato ad aggiungere la posizione del pin al di fuori dell'area di visualizzazione corrente della mappa ma ViewForAnnotation non viene mai attivato - ho pensato che questo dovrebbe essere quello che funziona, e mentre faccio scorrere la mappa e viene visualizzata all'interno l'area di visualizzazione corrente che dovrebbe attivare la funzione, ma non lo fa (dovrei notare che il pin viene visualizzato e visualizzato sulla mappa).

Ciò rende impossibile personalizzare il pin che desidero fare.

sto usando la stessa tecnica sulla mappa 1 che funziona perfettamente bene, ma per qualche motivo il ViewForAnnotation non viene mai chiamato all'interno Mappa 4.

Qualche suggerimento sarebbe molto apprezzato !!

+0

po 'di codice potrebbe aiutare il codice – shinoys222

+0

ho aggiunto. Ora noto che quando cambio da Map1 a Map4 di nuovo a Map1 solo alcune volte le mie annotazioni personalizzate vengono visualizzate con le immagini che voglio. Altre volte vengono visualizzati solo con un pin. –

+0

Ho giocato con più cose e penso che debba avere qualcosa a che fare con il delegato. Sebbene il delegato sia impostato, è come se non fosse impostato correttamente sull'istanza di MKMapView che viene visualizzata (nonostante sia impostato nella prima riga del metodo func loadMap4View (mV: MKMapView)). Potrebbe avere qualcosa a che fare con il parametro mV passato a una classe separata (passata per riferimento o tipo) ??? Qualche idea? –

risposta

9

ho riscontrato questo problema di tanto in time.And ho scoperto che a volte è necessario chiamare showAnnotations:animated: manualmente in questo modo:

mapView.showAnnotations(mapView.annotations, animated: true) 
+0

Sta funzionando leggermente meglio ma è ancora abbastanza glitch. ViewForAnnotation viene attivato quasi a caso e talvolta le immagini risultano al posto dell'annotazione del pin e altre volte non tanto. –

+0

@ M.Black Il problema può essere localizzato in 'mapView = mV'. Un modo più appropriato per farlo sarebbe: 1. rimuovi il vecchio mapview, 2.set il nuovo mapview's frame come il vecchio mapview, 3.add new mapview – wj2061

+0

Questa è la soluzione più vicina al funzionamento sebbene sia ancora apparentemente chiamata il metodo ViewForAnnotation in modo casuale e caricando solo le immagini appropriate un po 'di tempo. Scusa wj2061 che la taglia non ti è stata assegnata (non sono sicuro del motivo per cui è stata assegnata all'altra soluzione ???) –

3

Spiacente ma non riesco a vedere la dichiarazione del controller di visualizzazione mainVC: il controller implementa lo MKMapViewDelegate?

import MapKit 

class mainVC: UIViewController, MKMapViewDelegate 
{ 
    ... 
} 

EDIT 1: controllo anche se nel vostro controller della vista sul storyboard se il delegato è collegato con il controller in questo modo:

basta fare clic destro sul vostro MapView.

+0

Sì, sì. Così fanno tutte le altre classi –

+0

Il delegato è impostato nel codice (come è stato indicato sopra). Sono sorpreso che questa soluzione abbia ricevuto upvotes considerando che non spiega perché funziona un po 'di tempo e non altri. Esistono quattro classi diverse che gestiscono il caricamento di mapView su MainVC. Quindi, NON voglio che il delegato sia il controller di visualizzazione principale perché il codice è contenuto in altre classi di controller di visualizzazione per ciascuna delle singole mappe. –