为什么不调用ViewForAnnotation?

时间:2016-03-27 17:58:47

标签: ios swift2 mkmapview mkannotationview

我知道这个问题已被多次询问,但所有答案似乎与我的应用程序中的内容略有不同。

我的理解是,一旦mapView将其委托设置为显示它的ViewController,就会调用viewForAnnotation函数,并在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 - 显示从plist中读取的MKPolylines和自定义注释(继承自MKAnnotation)的组合 - 这非常有效!
  2. 地图2 - 显示从plist中读取的几个MKPolylines - 这非常有效!
  3. 地图3 - 显示从plist中读取的几个MKPolylines - 这非常有效!
  4. 地图4 - 应显示多个自定义注释 - 这不起作用!
  5. 以下是Map 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,animated:true))
    • 该类从plist读取并(使用帮助器类)构建一个自定义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")
      
    • 将其中的每一个添加到地图(mapView.addAnnotations),它们显示为引脚(它们正在显示)     mapView.addAnnotation(coords.allLocations![2])//这会添加一个Pin Annotation(可以工作),但从不调用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永远不会被触发 - 我认为这应该是有效的,并且我滚动'地图并显示在应该触发该功能的当前视图区域内,但它没有(我应该注意到该引脚正在显示并显示在地图上)。

    这使得我无法自定义我想要的引脚

    我使用与Map 1完全相同的技术,但由于某种原因,ViewForAnnotation永远不会在Map 4中调用。

    任何建议都将不胜感激!!

3 个答案:

答案 0 :(得分:11)

我经常遇到这个问题。我发现有时你需要像这样手动调用showAnnotations:animated:

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

答案 1 :(得分:5)

很抱歉,我看不到您的视图控制器声明 mainVC :您的控制器是否实现了MKMapViewDelegate

import MapKit

class mainVC: UIViewController, MKMapViewDelegate 
{
    ...
} 

编辑1:还要检查故事板上的视图控制器中是否有代理人与您的控制器链接,如下所示:

右键单击mapView。

答案 2 :(得分:0)

这是一个非常愚蠢的答案,但是今天对我造成了两次困扰,所以这里是:检查您的纬度/经度。如果交换了它们,那么您将有一个无效的点,或者是在海洋中央的一个点,因此将永远不会请求该视图,因为它可能在您的可见区域之外。