Обновить подзаголовок и изображение аннотации MapKit

Я немного поискал в Интернете и нашел несколько идей о том, как делать то, что я хочу, но мне все равно хотелось бы знать, что, по вашему мнению, мне следует делать.

Вот контекст:

Я разрабатываю приложение для iOS 5. Я использую MapKit для отображения карты и добавляю к нему около 5000 аннотаций - да, кажется, много, но не волнуйтесь, я использую библиотеку кластеризации :). Чтобы не загружать их каждый раз, когда пользователь открывает карту, я создаю их в моем appDelegate (я создаю массив аннотаций и вызываю [_mapView addAnnotations:[appDelegate.annotationsToAdd allObjects]];, когда открываю карту). Создание массива annotationsToAdd занимает около 10 секунд, поэтому я думаю, что это решение работает довольно хорошо (вам нужно подождать эти 10 секунд, прежде чем получить разрешение на открытие карты, но вы ждете только один раз при запуске приложения. ). В каждой из этих аннотаций у меня есть «ссылка» на объект, который содержит массив значений (15 чисел с плавающей запятой). На данный момент, когда я создаю аннотацию, метод subtitle возвращает одно из этих значений.

В ViewController моей карты у меня есть 2 сегментированных элемента управления. Первый имеет 3 сегмента, второй - 5, что дает 15 комбинаций - да, опять же, такое же количество значений имеет массив объекта в моей аннотации :).

Так что, возможно, вы заметили, что приближается моя проблема, я хотел бы обновить подзаголовок аннотации каждая на моей карте (даже те, что находятся в кластерах, поскольку кластер дает среднее значение на основе закрепленных в нем контактов. ). Я также хотел бы обновить цвет / изображение annotationView на основе значения подзаголовка аннотации.

Возможно, я ошибаюсь, но на основании своих исследований я понимаю, что вы должны удалить все аннотации и воссоздать их все для этого. вы понимаете, что это не вариант в моем случае. Я не могу заставить пользователя ждать 10 секунд каждый раз, когда он изменяет значение одного из элементов управления.

Я видел статью о KVO: может ли это быть рабочее решение?

Я мало что знаю о NSNotification, но стоит ли мне их использовать?

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

Заранее спасибо.


person rdurand    schedule 24.09.2012    source источник
comment
Можете ли вы опубликовать код контейнера данных и код, в котором вы хотите обновить субтитры? это может помочь сообществу SO с контекстом выработать ответ. например нужно ли менять сразу все аннотации? или вы могли бы жить с изменением их, когда они появляются, и вы можете читать аннотации? (конечно, никто не может прочитать все 5000 аннотаций одновременно, даже на дисплее Retina iPad, не так ли?) Вы можете позаимствовать теорию, которую Apple использует в iOS для TableView, где они запрашивают данные только для таблицы просматривать видимые ячейки.   -  person john.k.doe    schedule 01.10.2012


Ответы (2)


Прошу прощения, если я не совсем хорошо понял вашу ситуацию, но я чувствую, что двигаюсь к решению аналогичной проблемы, поэтому я постараюсь поделиться с вами своими мыслями. Я буду использовать ваши слова в качестве руководства для своего ответа:

"вы должны подождать эти 10 секунд, прежде чем получить разрешение на открытие карты"

Знаете ли вы о следующих <MKOverlayView> методах протокола (см. http://developer.apple.com/library/IOs/#documentation/MapKit/Reference/MKOverlayView_class/Reference/Reference.html):

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale

(Предполагая, что у вас есть 5000 контактов на всей карте мира, а не на каждом fx 1 км, т.е. не ТАКОЕ БОЛЬШОЕ количество контактов) Вы можете разделить свои пять тысяч на части, чтобы каждая часть контактов была заполнена соответствующим MKMapRect регионом. который рисуется на карте. Таким образом, ваша карта заполняется булавками / аннотациями по запросу только для определенного региона в любой момент времени. В зависимости от вашей ситуации это может значительно ускорить работу.

Это очень хорошая демонстрация работы с MKMapRect плитками: https://github.com/mtigas/iOS-MapLayerDemo - заполнять информацией только определенные части карты. Также вы можете google что-нибудь вроде «Карты размером 256 пикселей», чтобы понять, как рисуются карты.

«Я понимаю, что для этого вам необходимо удалить все аннотации и воссоздать их все».

Зачем воссоздавать? У вас есть доступ ко всем аннотациям, которые уже есть на вашей карте - почему бы просто не перебрать связанные классы аннотаций и не обновить их субтитры?

Примерно так:

Я надеюсь, что мои замечания касаются объема вашего вопроса / ситуации.

person Stanislav Pankevich    schedule 30.09.2012
comment
Нет необходимости выяснять, когда появляются аннотации - просто добавьте их все сразу, как описано в документации: developer.apple.com/library/ios/#Documentation/MapKit/Reference/ - person Aaron Brager; 01.10.2012
comment
Привет. Спасибо за ответ. К сожалению, 5000 контактов находятся не на всей карте мира, а локализованы только в 2 городах ... Поскольку я задал свой вопрос, я увидел, что могу использовать KVO (как также предложил Аарон в своем ответе) для обновления моего аннотации просмотров. Я займусь этим. Еще раз спасибо. - person rdurand; 01.10.2012

Прежде всего, вы должны просто добавлять аннотации сразу, не используя библиотеку кластеризации:

При настройке интерфейса карты вы должны сразу же добавить все объекты аннотации. Вид карты использует данные координат в каждом объекте аннотации, чтобы определить, когда соответствующий вид аннотации должен появиться на экране.

(Из справочника по классам MKMapView ).

MKMapView будет управлять ими за вас, чтобы ваше приложение не замедлялось. Этот подход, вероятно, не будет медленнее, чем то, что вы делаете, и тогда вы теоретически могли бы сделать:

[mapView removeAnnotations:mapView.annotations];
//add your annotations here

если вы хотите удалить их все, а затем снова добавить их.

Однако вы ошибаетесь, что вам нужно удалить их все сразу. Если вам известна конкретная аннотация, вы можете просто сделать:

[mapView removeAnnotation:someAnnotation];
[mapView addAnnotation:someOtherAnnotation];

Если у вас есть замены в NSArray, вы можете даже:

[mapView removeAnnotations:arrayOfOldAnnotations];
[mapView addAnnotations:arrayOfNewAnnotations];

Наконец, если вы хотите изменить аннотацию, вы можете сделать это с помощью KVO (см. этот стек Вопрос о переполнении), но его так же легко удалить, а затем добавить, и пользователь не заметит, пока вы не анимируете добавление.

person Aaron Brager    schedule 01.10.2012
comment
Привет. Я добавляю все аннотации сразу, библиотека кластеризации просто перегруппировывает отображаемые представления аннотаций. Я не имел в виду, что не могу удалить / добавить одну аннотацию, я имел в виду, что поскольку все мои аннотации меняются сразу, я думаю, что у меня , чтобы удалить все виды и добавить их обратно. В любом случае, я подумаю об использовании KVO (как я сказал в своем комментарии в ответе Станислава, я не знал, что могу это сделать в то время), но решение итерации через аннотации, как предложил Станислав, может быть лучше для моей ситуации. Спасибо за ответ. - person rdurand; 01.10.2012