Objective c iOS:加载MKMapView并添加批注/覆盖时的通知?

Objective c iOS:加载MKMapView并添加批注/覆盖时的通知?,objective-c,ios,cocoa-touch,mkmapview,mapkit,Objective C,Ios,Cocoa Touch,Mkmapview,Mapkit,我知道在地图加载以及添加注释和覆盖时,用于通知我的委托方法。(mapViewDidFinishLoadingMap:mapView:DidAddAnnotationView:mapView:DidAddOverlayView:) 我想在加载所有内容后,从我的MKMapView创建一个UIImage。目前,我正在创建一次我的UIImage,调用mapView:DidAddOverlayView:,但这并不总是可靠的,因为有时需要更长的时间才能添加覆盖,有时会多次调用mapViewDidFinish

我知道在地图加载以及添加注释和覆盖时,用于通知我的委托方法。(
mapViewDidFinishLoadingMap:
mapView:DidAddAnnotationView:
mapView:DidAddOverlayView:

我想在加载所有内容后,从我的
MKMapView
创建一个
UIImage
。目前,我正在创建一次我的
UIImage
,调用
mapView:DidAddOverlayView:
,但这并不总是可靠的,因为有时需要更长的时间才能添加覆盖,有时会多次调用
mapViewDidFinishLoadingMap:
,或者加载需要很长时间。有时不调用它,因为分片是缓存的。因此,很难确切地知道什么时候所有东西都加载了。我试过使用计时器,但这也不能保证它的可靠性

我的问题是,我如何知道何时所有内容都已完全加载,包括所有地图分幅、所有注释和所有覆盖?好的,您可以在代理中设置三个标志:

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

…然后在
MapViewWillStartingMap:
方法中将所有三个标志设置回
NO
。在缓存地图分幅但新覆盖和新注释都会滚动到屏幕上的情况下,这可能会创建一个略多于必要的图像-如果您想防止出现这种情况,可以使用
UIPangestureRecognitizer
来检测用户何时平移或挤压地图,并相应地将这两个标志重置为
NO

如果你不想“地图视图”,这相对容易。我一下子画出了一些东西,把我所有的请求都写进了一个总数。我存储了“请求”的总数,当它们完成加载函数时,我检查了“if requests left==0”或类似值,然后调用了“Draw everything after”

因此,您要做的是将3种不同的类型添加到“运行总数”(因为队列本身在Comp Sci中不同,试图避免词汇冲突),然后在它们“用完”时,通过“Draw rect”调用或“init with coder”如果它是一个Xib注释或任何你能保证的函数,因为iOS UIView子类绝对没有像其他编程语言一样的公共初始化函数(单独的rant),基本上init调用一个公共类上的函数,singleton,static int,delegate,以两者中的任何一个为准,然后查看它何时用完-


我知道你的项目结束了,但是有这么多人投了赞成票,我想答案不会有什么坏处。如果目标C有一个构造函数,这个答案会简单得多。无论采用哪种方式,这都应该解决问题,只需花费一些思考和时间,因为每个项目都需要明确如何实施它。

这是一个老问题,但如果您使用的是iOS 7,只需使用mapView mapViewDidFinishRenderingMap委托即可

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

}

以下代码适用于Swift 1.2中的iOS 8.4

func mapViewDidFinishRenderingMap(mapView: MKMapView!, fullyRendered: Bool) {
    // Your code on rednering completion
}

mapViewDidFinishRenderingMap
的问题在于,它只包括地图分幅本身的加载,而不包括分幅和注释的加载。为此,可以使用
didAddAnnotationViews
。为了安全起见,我建议观察这两种情况,并使用稍后返回的方法

我已经尝试了其他答案的所有方法

至少在iOS 11.1上,似乎不可能获得完全加载的时间

我从VKMapView对象中发现了未记录的通知VKMapView IDBECOMEFULLYDRAWNNotification,但即使它发生得太早


所以看起来只有一种方法存在——等待几秒钟,等待满载,然后用手指交叉,希望地图加载完成。

是的,我以前想过这样做。从我所看到的mapViewDidFinishLoadingMap:在加载缓存的分幅时不会被调用。因此,这是不可靠的。这就是
uipangestureerecognizer
的作用,在地图不加载分幅的情况下,将注释和覆盖标志重置为
NO
。不过,可能仍然存在一个问题:除非你的注释和覆盖层太厚,以至于每次用户滚动地图时都会添加一个注释和覆盖层,您不会每次都将所有三个标志设置为
YES
,而且根据我的经验,测试新滚动到的视图区域是否包含覆盖和注释的成本太高,无法实时执行。此
MKMapView
上没有平移功能。我正在从它创建一个
UIImage
,这就是为什么我需要知道什么时候加载了所有内容,这样我就可以在加载了所有内容的情况下获得一个很好的地图图像。嗯。在这种情况下,您是否应该能够使用
MapViewWillStartingMap:
方法来检测地图何时从服务器下载地图分幅?如果调用了
mapViewWillStartLoadingMap:
,则需要设置一个标志,并等待
mapViewDidFinishLoadingMap:
;如果未调用
mapViewWillStartLoadingMap:
,则您正在使用缓存的磁贴,无需等待。最初将标志设置为“是”,然后在
MapViewWillStartingMap:
中将其设置为“否”,可能会起作用。我再次认为,MapViewWillStartingMap:将不可靠,因为如果存在缓存的分幅,它将不会被调用。我怎么知道mapViewWillStartLoadingMap:是否不会被调用,或者连接速度慢需要很长时间?我想您可以尝试使用从0开始的计数器变量,我假设您知道要添加的注释数量,以便进行比较。。方法-(MKAnnotationView*)mapView:(MKMapView*)mapView viewForAnnotation:(id)注释将从您要添加的每个注释中调用,增加方法内的计数器,如果达到注释总数,则调用PerformSelect的capture image函数,并延迟一段时间以达到精确的完美效果。。我认为它应该行得通1.我不是s