iOS: Уведомление о загрузке MKMapView и добавлении аннотаций / наложений? - PullRequest
21 голосов
/ 07 декабря 2011

Мне известны методы делегатов, используемые, чтобы сообщить мне, когда карта загружена, а также добавлены аннотации и наложения.(mapViewDidFinishLoadingMap: mapView:didAddAnnotationViews: mapView:didAddOverlayViews:)

Я хочу создать UIImage из моего MKMapView, как только все загрузится.В настоящее время я создаю UIImage, как только вызывается mapView:didAddOverlayViews:, но это не всегда надежно, потому что иногда наложение занимает больше времени, иногда mapViewDidFinishLoadingMap: вызывается более одного раза, или загрузка занимает много времени.Иногда это НЕ вызывается, потому что тайлы кэшируются.Так что очень трудно точно знать, когда все загрузилось.Я пытался использовать таймер, но это также не делает его надежным.

Мой вопрос: как я могу знать, когда все полностью загрузилось, включая все фрагменты карты, все аннотации и все наложения?

Ответы [ 6 ]

22 голосов
/ 24 января 2014

Это старый вопрос, но если вы используете iOS 7, просто используйте делегат mapView mapViewDidFinishRenderingMap.

- (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
{
    // Image creation code here

}
4 голосов
/ 30 сентября 2015

Следующий код работает на iOS 8.4 в Swift 1.2

func mapViewDidFinishRenderingMap(mapView: MKMapView!, fullyRendered: Bool) {
    // Your code on rednering completion
}
1 голос
/ 27 августа 2016

Проблема с mapViewDidFinishRenderingMap состоит в том, что она включает в себя только загрузку самих плиток карты, но не плиток плюс аннотации.Для этого вы можете использовать didAddAnnotationViews.Чтобы быть в безопасности, я бы порекомендовал наблюдать и то, и другое, которое когда-либо вернется позже.

0 голосов
/ 13 ноября 2017

Я пробовал все способы из других ответов.

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

Я нашел недокументированное уведомление VKMapViewDidBecomeFullyDrawnNotification от VKMapViewобъект, но даже это происходит слишком рано.

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

0 голосов
/ 21 февраля 2013

Это сравнительно легко, если вы отвлекаетесь от «вида карты». То, что я сделал с графиком чего-то сразу, заключалось в том, чтобы собрать все мои запросы в общую сумму. Я сохранил общее количество «запросов», и когда они закончили свою функцию загрузки, я проверил «если осталось запросов == 0» или подобное, затем я вызвал «Рисовать все после».

Таким образом, вы должны сделать так, чтобы 3 отдельных типа добавлялись к «итоговой сумме» (поскольку сама очередь отличается в Comp Sci, пытаясь избежать словарного конфликта), затем, когда они «заканчиваются», через их вызов "Draw rect" или "init with coder", если это аннотация Xib или любая другая функция, которую вы можете гарантировать, так как подклассы iOS UIView не имеют абсолютно никакой общей функции инициализации, как у любого другого языка программирования (отдельный rant), в основном, что init вызывает функцию на общий класс, singleton, static int, делегат, в зависимости от того, что происходит, а затем посмотрите, когда он закончится -.

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

0 голосов
/ 19 декабря 2011

Ну, вы могли бы установить три флага в своем делегате:

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
    didFinishLoadingMap = YES;
    [self createImage];
}

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    didFinishAddingAnnotationViews = YES;
    [self createImage];
}

- (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews

{
    didFinishAddingOverlayViews = YES;
    [self createImage];
}

... а затем

- (void)createImage
{
    if (didFinishLoadingMap && didFinishLoadingAnnotationViews && didFinishAddingOverlayViews) {
        // Create the image
    }
}

... и затем установите все три флага обратно на NO в вашем методе mapViewWillStartLoadingMap:. Это может создать изображение несколько чаще, чем необходимо, в сценарии, в котором кешируются фрагменты карты, но на экран прокручиваются как новые наложения, так и новые аннотации - если вы хотите защититься от этого, вы можете использовать UIPanGestureRecognizer, чтобы определить пользователь панорамирует или сжимает карту и сбрасывает эти два флага на NO соответственно.

...