2017-01-26 2 views
0

Так что для моего MAPview, я получаю координаты из другого VC, передавая его долготы и широты через глобальный массив, как, например:Swift MapView не добавлять аннотации к карте

Добавление широты и долготы в массив:

var location_one: [String: Any] = ["title": eventName, "latitude": latitude, "longitude": longitude] 
    locations.append(location_one) 
    if let tbc = self.tabBarReference { 
     if let map = tbc.viewControllers?[1] as? MapVC { 
      map.loadViewIfNeeded() 
      map.add(newLocation:location_one) 
     } 
    } 

Получение координат на MapViewVC:

func add(newLocation location_one:[String:Any]) { 
     let momentaryLat = (location_one["latitude"] as! NSString).doubleValue 
     let momentaryLong = (location_one["longitude"] as! NSString).doubleValue 
     let annotation = MKPointAnnotation() 
     annotation.title = location_one["title"] as? String 
     annotation.coordinate = CLLocationCoordinate2D(latitude: momentaryLat as CLLocationDegrees, longitude: momentaryLong as CLLocationDegrees) 
     map.addAnnotation(annotation) 

     //  self.map.centerCoordinate = annotation.coordinate 
    } 

viewForannotation код:

func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 



    let identifier = "pinAnnotation" 
    var annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView 

    if annotationView == nil { 
     annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) 
     annotationView?.canShowCallout = true 
    } 

    annotationView?.annotation = annotation 
    return annotationView 
} 

Координаты должным образом передаются, и функция func add вызывается (проверяется с использованием оператора break), однако, когда я перехожу к MapView в симуляторе, аннотация не помещается. Я понятия не имею, что происходит, поскольку это правильно работало в другом тестируемом приложении, но не имеет понятия, что может заставить его испортиться.

У меня также есть код, который находит текущее местоположение пользователя и помещает контакт на основе этого ... возможно, это может испортить код кодов добавления?

+0

Неправильно ли вы делегировали делегат объекту карты и реализовали метод viewForAnnotation? – apineda

+0

@Rob the momentaryLat и momentaryLong получить координаты должным образом, поэтому я думаю, что эта часть хороша. Я редактировал свой вопрос, чтобы включить viewForAnnotation. Мое приложение правильно работало с отображением аннотации текущего местоположения, поэтому я не уверен, правильно ли я это сделал или нет. – Kevin

+0

@apineda yep I set, self.map.delegate = self в моем представленииDidLoad(). Кроме того, я отредактировал свой вопрос, чтобы включить мой метод viewForAnnotation, однако я не уверен, правильно ли я его реализовал. – Kevin

ответ

2

Я предлагаю дважды проверить числовые значения momentaryLat и momentaryLong, так как возможно, что из-за проблем с анализом они не такие, какие вы думаете (например, убедитесь, что они не 0.0, в Атлантическом океане !). Мы должны были бы увидеть, что были значения location_one["latitude"], прежде чем преобразовать их в NSString и извлечь из них двойное значение. Разбейте его на отдельные шаги, и проблема, скорее всего, выскочит на вас.


Ваш viewFor выглядит хорошо. Не связанный, я бы предложил поместить annotationView?.annotation = annotation в предложение else предыдущего if (нет необходимости устанавливать annotation, если вы только что создали MKPinAnnotationView, используя тот же самый annotation ... вам нужно сделать это только при повторном использовании аннотационного представления) , И я также, как правило, проверял, чтобы аннотация не была MKUserLocation, потому что мы обычно позволяем отображать представление карты для нас.

func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
    if annotation is MKUserLocation { return nil } // let the OS show user locations itself 

    let identifier = "pinAnnotation" 
    var annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView 

    if annotationView == nil { 
     annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) 
     annotationView?.canShowCallout = true 
    } else { 
     annotationView?.annotation = annotation 
    } 

    return annotationView 
} 

Но ни одно из этих двух наблюдений не имеет ничего общего с вашей проблемой недостающей аннотации.


Помните, метод viewForAnnotation (или viewFor в Swift 3) вызывается только, когда один или несколько из МАП annotations имеет coordinate, попадающий в видимой части карты, и, следовательно, делает вывод о том, что она должна визуализировать связанные аннотации. Таким образом, нельзя было ожидать, что он будет вызван до тех пор, пока (а) карта не попытается нарисовать себя, и (б) одна или несколько аннотаций имеют координаты внутри (или вблизи) видимой части карты.

Например, если к объекту карты добавлено 100 аннотаций, из которых только 10 попадают в видимую часть карты, будет создано всего 10 аннотаций. И если вы прокрутите карту таким образом, чтобы 5 выпадали из поля зрения, а еще 7 прокручивались в поле зрения, она вызывала viewForAnnotation еще 7 раз, один раз для каждой вновь видимой аннотации. Функция viewForAnnotation, скорее всего, успешно удалит/повторно использует 5 аннотаций, которые прокручиваются вне поля зрения, и будет создавать только новые аннотации для двух дополнительных. (Это сложнее, но это основная идея.)

Это аналогично представлениям таблицы/коллекции, где ячейки создаются только для видимых ячеек. Итак, если у вас есть 100 объектов в вашей модели, но только 12 строк видны в таблице, вы создадите только 12 ячеек. И когда строка прокручивается из поля зрения, она становится доступной для удаления/повторного использования для будущих строк, которые прокручиваются в представлении. Это общий шаблон, который вы увидите на протяжении всего iOS, где вычислительно дорогие объекты просмотра создаются по мере необходимости и повторно используются везде, где это возможно.

+0

Разрушение помогло немного! Я понял, что мой код для ввода координат в моем массиве оказался не в нужном месте. Теперь, после запуска, выход для location_one ["широта"] является необязательным ("40.713054"), а мгновенная широта выводит 40.713054; однако он по-прежнему не размещает аннотацию на месте. – Kevin

+0

ОК, поэтому у вас есть навыки отладки, чтобы понять это. Посмотрите на значение «координат» объекта аннотации прямо перед добавлением его в массив «аннотаций» карты.Посмотрите на это в 'viewFor'. Является ли аннотация просто не в нужном месте или она не добавляется вообще по какой-то причине? – Rob

+0

Я понимаю, что делает метод viewFor, но мне трудно понять каждую строку кода внутри. Я не совсем уверен, что вы хотите найти значение координаты аннотации в viewFor. Аннотации перед добавлением в массив: CLLocationCoordinate2D (широта: 40.713054, долгота: -74.007). И аннотация не помещается вообще. – Kevin

Смежные вопросы