- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用自定义 MKOverlay/MKOverlayView
用我自己的异步加载的图 block 完全覆盖 Google basemap 。当我收到对覆盖 View 的 canDrawMapRect:zoomScale:
调用(并在这种情况下返回 FALSE)时,我遵循请求卸载图 block 的模式,然后调用 setNeedsDisplayInMapRect:zoomScale:
一旦瓷砖可用。
这一切通常都有效,并且在模拟器中似乎完美运行。
但是,在设备上,我有时会在叠加层中看到一个“洞”——缺失的图 block 。
我可以看到该图 block 已被请求,并且请求已完成。我可以看到我调用了 setNeedsDisplayInMapRect:zoomScale:
,并且我正在传递 canDrawMapRect 中提供的原始
。但我也可以看到,从未要求叠加层重绘该图 block (MKMapRect
和 MKZoomScale
:缩放比例:canDrawMapRect:zoomScale:
和 drawMapRect:zoomScale:inContext:
都不再为该图 block 调用) .
我需要了解为什么会发生这种情况以及如何纠正它。
这是我的 MKOverlayView 子类的相关代码:
- (BOOL) canDrawMapRect: (MKMapRect) mapRect zoomScale: (MKZoomScale) zoomScale
{
NSUInteger zoomLevel = [self zoomLevelForZoomScale:zoomScale];
CGPoint mercatorPoint = [self mercatorTileOriginForMapRect:mapRect];
NSUInteger tilex = floor(mercatorPoint.x * [self worldTileWidthForZoomLevel:zoomLevel]);
NSUInteger tiley = floor(mercatorPoint.y * [self worldTileWidthForZoomLevel:zoomLevel]);
NSURL* tileUrl = [self tileURLForZoomLevel: zoomLevel tileX: tilex tileY: tiley];
ASIHTTPRequest* tileRequest = [ASIHTTPRequest requestWithURL: tileUrl];
tileRequest.downloadCache = [ASIDownloadCache sharedCache];
[tileRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
if ( NO == [[ASIDownloadCache sharedCache] isCachedDataCurrentForRequest: tileRequest] )
{
[tileRequest setCachePolicy: ASIAskServerIfModifiedWhenStaleCachePolicy];
tileRequest.delegate = self;
tileRequest.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
[NSValue value: &mapRect withObjCType: @encode( MKMapRect )], @"mapRect",
[NSValue value: &zoomScale withObjCType: @encode( MKZoomScale )], @"zoomScale",
[NSNumber numberWithInt: tilex], @"tilex",
[NSNumber numberWithInt: tiley], @"tiley",
nil];
[_tileRequestStack addOperation: tileRequest];
NSLog( @"canDrawMapRect: %d, %d - REQUESTING", tilex, tiley );
return NO;
}
NSLog( @"canDrawMapRect: %d, %d - READY", tilex, tiley );
return YES;
}
- (void) drawMapRect: (MKMapRect) mapRect zoomScale: (MKZoomScale) zoomScale inContext: (CGContextRef) context
{
NSUInteger zoomLevel = [self zoomLevelForZoomScale:zoomScale];
CGPoint mercatorPoint = [self mercatorTileOriginForMapRect:mapRect];
NSUInteger tilex = floor(mercatorPoint.x * [self worldTileWidthForZoomLevel:zoomLevel]);
NSUInteger tiley = floor(mercatorPoint.y * [self worldTileWidthForZoomLevel:zoomLevel]);
NSLog( @"drawMapRect: %d, %d", tilex, tiley );
NSURL* tileUrl = [self tileURLForZoomLevel: zoomLevel tileX: tilex tileY: tiley];
NSData* tileData = [[ASIDownloadCache sharedCache] cachedResponseDataForURL: tileUrl];
UIGraphicsPushContext(context);
if ( tileData != nil )
{
UIImage* img = [UIImage imageWithData: tileData];
if ( img != nil )
{
[img drawInRect: [self rectForMapRect: mapRect] blendMode: kCGBlendModeNormal alpha: 1.0 ];
}
else
{
NSLog( @"oops - no image" );
}
CGSize s = CGContextConvertSizeToUserSpace( context, CGSizeMake( 40, 1 ));
UIFont* f = [UIFont systemFontOfSize: s.width];
[[UIColor blackColor] setFill];
[[NSString stringWithFormat: @"%d,%d", tilex, tiley] drawInRect: [self rectForMapRect: mapRect] withFont: f];
}
UIGraphicsPopContext();
}
- (void) requestFinished: (ASIHTTPRequest *) tileRequest
{
NSValue* mapRectValue = [tileRequest.userInfo objectForKey: @"mapRect"];
MKMapRect mapRect; [mapRectValue getValue: &mapRect];
NSValue *zoomScaleValue = [tileRequest.userInfo objectForKey:@"zoomScale"];
MKZoomScale zoomScale; [zoomScaleValue getValue: &zoomScale];
NSLog( @"requestFinished: %d, %d, %lf",
[[tileRequest.userInfo objectForKey:@"tilex"] intValue],
[[tileRequest.userInfo objectForKey:@"tiley"] intValue],
zoomScale );
[self setNeedsDisplayInMapRect: mapRect zoomScale: zoomScale];
}
最佳答案
我遇到的问题与此处描述的问题非常相似。在我的例子中,我无法重现所需的行为(在 http://developer.apple.com/library/ios/documentation/MapKit/Reference/MKOverlayView_class/Reference/Reference.html#//apple_ref/occ/instm/MKOverlayView/setNeedsDisplayInMapRect:zoomScale 中描述),即使是最简单的代码也是如此:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
return NO;
}
或更接近我的原始代码:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
[SomeAsynchronousRequestWithCompletionHandler:^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
}];
return NO;
}
在这两种情况下,setNeedsDisplayInMapRect:zoomScale: 从未被调用过一次。
情况发生了变化,当我开始在 dispatch_async 中运行 setNeedsDisplayInMapRect:zoomScale: 时,dispatch_async 被调度到 canDrawMapRect 运行所在的同一队列,例如:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
dispatch_queue_t queue = dispatch_get_current_queue();
NSLog(@"This should trace forever");
dispatch_async(queue, ^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
});
return NO;
}
或包含异步作业:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
dispatch_queue_t queue = dispatch_get_current_queue();
[SomeAsynchronousRequestWithCompletionHandler:^{
dispatch_async(queue, ^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
});
}];
return NO;
}
使用 dispatch_async - 我可以看到 “This should trace forever” 字符串被无休止地跟踪。我原来的问题也完全消失了。
稍后更新:目前,我使用 dispatch_get_main_queue() 来调用 setNeedsDisplayInMapRect:zoomScale: 就像
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
[SomeAsynchronousRequestWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
});
}];
return NO;
}
关于ios - setNeedsDisplayInMapRect 不触发新的 drawMapRect : call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10128447/
在我的 MKOverlayView 中,我在绘制传递给 drawMapRect:mapRect:zoomScale:inContext 的 MKMapRect 之外的区域时遇到问题派生类。我试图为集合
我正尝试在我的 map View 上绘制圆圈,但正如我所注意到的 - 方法 (void)drawMapRect 已被弃用。有什么新东西或任何替代品吗?谢谢。 最佳答案 如 the documentat
我在 map 上有很多长折线。我想优化他们的绘图,因为在几千个点上,折线的绘制速度非常慢。 我的 drawMapRect 看起来像这样: - for each polyline segment - v
我在修改 Breadcrumb 示例时遇到了一些不一致之处,以使 CrumbPathView 从 MKOverlayPathView 子类化(就像它应该的那样),而不是从 MKOverlayView
我重写了 .m 文件中的 drawMapRect 方法,但重写方法中的某些代码行似乎给了我错误,我不确定如何解决。我确保将 mkmapview 委托(delegate)设置为 self,导入了所有正确
我正在使用自定义 MKOverlay/MKOverlayView 用我自己的异步加载的图 block 完全覆盖 Google basemap 。当我收到对覆盖 View 的 canDrawMapRec
我构建了一个自定义 MKOverlayRenderer 以构建多边形、应用混合模式,然后将它们添加到 map View 。在我的 drawMapRect 函数中,我使用 CGPoints 数组来构建多
我有这个功能: - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContext
我是一名优秀的程序员,十分优秀!