2016-03-27 3 views
9

Я знаю, что этот вопрос задавался несколько раз, однако все ответы кажутся немного отличающимися от того, что происходит в моем приложении.Почему ViewForAnnotation не называется?

Я понимаю, что функция viewForAnnotation вызывается после того, как mapView имеет свой делегат, установленный в ViewController, в котором он отображается, и добавление аннотации к карте, когда mapView прокручивается так, что она отображается внутри области mapView ,

В настоящее время у меня есть один главный ViewController (mainVC), который содержит один MKMapView (MAPview) Этот ViewController контролирует четыре карты, которые будут отображаться в 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() 
    } 
} 

Есть несколько различных классов, которые управляют работой каждого из различных карт:

  1. Карта 1 - Отображает комбинацию MKPolylines и пользовательские аннотации (наследуется от MKAnnotation), которые считываются из plist - Это отлично работает!
  2. Карта 2 - отображает несколько MKPolylines, считанных с plist - это отлично работает!
  3. Карта 3 - отображает несколько MKPolylines, считанных с plist - это отлично работает!
  4. Карта 4 - Должен отображать несколько пользовательских аннотаций - это НЕ РАБОТАЕТ!

Вот что происходит с картой 4:

  • MKMapView будет загружен неправильно

    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 
    

    }

  • набор делегата в MAPview к текущему классу (mapView.delegate = self)

  • она наезжает на нужном месте (mapView.setRegion (coordinateRegion, анимированные: правда))
  • класс считывает из списка свойств и (используя вспомогательный класс) создает массив пользовательских MKAnnotations (CemAnno)

  • места хранятся в массиве под названием 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") 
    
  • добавляет EAC h один из них к карте (mapView.addAnnotations), и они отображаются в виде выводов (они отображаются) mapView.addAnnotation (coords.allLocations! [2]) // Это добавляет одну единственную Pin-аннотацию (которая работает), но никогда не вызывает функцию viewForAnnotation

Это работает, однако, я пытаюсь настроить аннотации, которые показываются, но функция ViewForAnnotation никогда не называется ????

// 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() 
} 

Я попытался добавить расположение булавки внутри текущего просмотр области карты, но ViewForAnnotation никогда не увольняет. Я попытался добавить местоположение штифта за пределы текущей области обзора карты, но ViewForAnnotation никогда не запускается - я решил, что это должно быть то, что работает, и когда я «прокручиваю» карту, и она появляется внутри текущую область обзора, которая должна запускать функцию, но это не так (я должен отметить, что вывод отображается и отображается на карте).

Это делает так, что я не могу настроить контакт, который я бы хотел сделать.

Я использую ту же технику, как на карте 1, который работает прекрасно, но по какой-то причине ViewForAnnotation никогда не называется внутри Карта 4.

Любые предложения будут высоко оценены !!

+0

некоторый код может помочь – shinoys222

+0

я добавил код. Теперь я замечаю, что когда я перехожу с Map1 на Map4 обратно в Map1, только некоторые из них - это мои пользовательские аннотации, показываемые с изображениями, которые я хочу. В других случаях они отображаются только с булавкой. –

+0

Я играл с несколькими вещами, и я думаю, что это должно иметь какое-то отношение к делегату. Несмотря на то, что делегат установлен, он выглядит так, как будто он не установлен правильно для экземпляра MKMapView, который отображается (несмотря на то, что он установлен в первой строке метода func loadMap4View (mV: MKMapView)). Может ли это иметь какое-то отношение к параметру mV, передаваемому отдельному классу (передается по ссылке или типу) ??? Есть идеи? –

ответ

9

Я столкнулся с этой проблемой время от time.And я обнаружил, что иногда вам нужно позвонить showAnnotations:animated: вручную, как это:

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

Он работает немного лучше, но все еще довольно смущен. Функция ViewForAnnotation запускается практически произвольно, а иногда получается результат изображения вместо аннотации вывода, а иногда и не столько. –

+0

@ M.Black Проблема может найти в «mapView = mV». Более подходящим способом сделать это будет: 1. удалить старый mapview, 2.set новый кадр mapview, такой же, как старый mapview, 3.add new mapview – wj2061

+0

Это самое близкое решение для работы, хотя оно по-прежнему, по-видимому, вызывает метод ViewForAnnotation случайным образом и загружает соответствующие изображения только некоторое время. Извините wj2061, что награда не была присуждена вам (я не уверен, почему она была присуждена другому решению ???) –

3

Извините, но я не вижу декларации вашего контроллера вида mainVC: ваш контроллер реализует MKMapViewDelegate?

import MapKit 

class mainVC: UIViewController, MKMapViewDelegate 
{ 
    ... 
} 

EDIT 1: проверка также, если в вашем контроллере представления на раскадровку, если делегат связан с контроллером, как это:

просто кликните правой кнопкой мыши на вашем MAPview.

+0

Да, да. Таким образом, все остальные классы –

+0

Делегат установлен в код (как указано выше). Я удивлен, что это решение получило upvotes, учитывая, что он не объясняет, почему он работает некоторое время, а не другие. Существует четыре разных класса, которые обрабатывают загрузку mapView на MainVC. Поэтому я НЕ хочу, чтобы делегат был основным контроллером представления, потому что код содержится в других классах контроллера классов для каждой из отдельных карт. –