Ios 使用CATiledLayer';s drawLayer:inContext:

Ios 使用CATiledLayer';s drawLayer:inContext:,ios,map,uiscrollview,catiledlayer,Ios,Map,Uiscrollview,Catiledlayer,我正在尝试使用CATiledLayer+UIScrollView实现自己的地图引擎 在我实现的drawLayer:inContext:方法中,如果当前边界框需要某个平铺图像,我会立即在上下文中绘制它 但是,当本地缓存数据结构中没有可用的磁贴图像时,会从磁贴服务器异步请求/下载磁贴图像,而不会在上下文中绘制任何内容 问题是,当我不在上下文中绘制任何内容时,视图的该部分显示为空白平铺。预期的行为是从上一个缩放级别显示缩放的平铺视图 如果你们遇到过任何类似的问题并找到了解决方案,请告诉我。您必须在获得

我正在尝试使用
CATiledLayer
+
UIScrollView
实现自己的地图引擎

在我实现的
drawLayer:inContext:
方法中,如果当前边界框需要某个平铺图像,我会立即在上下文中绘制它

但是,当本地缓存数据结构中没有可用的磁贴图像时,会从磁贴服务器异步请求/下载磁贴图像,而不会在上下文中绘制任何内容

问题是,当我不在上下文中绘制任何内容时,视图的该部分显示为空白平铺。预期的行为是从上一个缩放级别显示缩放的平铺视图


如果你们遇到过任何类似的问题并找到了解决方案,请告诉我。

您必须在获得数据后立即为磁贴设置显示需求。在平铺可用之前,您必须将其视为空白,因为您无法影响正在创建的平铺CATiledLayer

您的
CATiledLayer
应该按照您的预期从上一个缩放级别提供此平铺。对于平铺层,您的
levelsOfDetail
levelsOfDetailBias
设置为什么

我也这样做,在下载磁贴之前阻塞线程。性能好,运行平稳。我使用队列来存储每个磁贴请求,因此我还可以取消那些不再有用的磁贴请求

为此,请在启动异步磁贴请求后立即使用锁停止线程,并在缓存磁贴后立即解除锁定


听起来不错吧?这对我有用

您必须调用setNeedsDisplay或setNeedsDisplayInRect:但问题是,如果您调用此函数,它将重新绘制scrollView中的每个磁贴。因此,尝试使用UIView的子类而不是CATiledLayer子类,并像这样实现TiledView(UIView的子类)

对于scrollView

UIScrollView* sv = [[UIScrollView alloc] initWithFrame:
                    [[UIScreen mainScreen] applicationFrame]];
sv.backgroundColor = [UIColor whiteColor];
self.view = sv;
CGRect f = CGRectMake(0,0,3*TILESIZE,3*TILESIZE);
TiledView* content = [[TiledView alloc] initWithFrame:f];
float tsz = TILESIZE * content.layer.contentsScale;
[(CATiledLayer*)content.layer setTileSize: CGSizeMake(tsz, tsz)];
[self.view addSubview:content];
[sv setContentSize: f.size];

这实际上是一个答案还是只是对这个问题的一个评论?嗯,我想这是一个答案,因为我有同样的问题,我解决了它。我没有代码显示在这里(我仍在工作),但解决方法是有效的。也许我没有解释清楚。我的意思是,我确实在等待请求,所以我总是在上下文中画一些东西。如果他意识到绩效影响,我的经验是,这根本不会造成任何影响。但为了避免重复请求,您必须缓存这些分幅。如果你需要密码,我可以今晚或明天提供。
UIScrollView* sv = [[UIScrollView alloc] initWithFrame:
                    [[UIScreen mainScreen] applicationFrame]];
sv.backgroundColor = [UIColor whiteColor];
self.view = sv;
CGRect f = CGRectMake(0,0,3*TILESIZE,3*TILESIZE);
TiledView* content = [[TiledView alloc] initWithFrame:f];
float tsz = TILESIZE * content.layer.contentsScale;
[(CATiledLayer*)content.layer setTileSize: CGSizeMake(tsz, tsz)];
[self.view addSubview:content];
[sv setContentSize: f.size];