使用CATiledLayer的drawLayer:inContext:

时间:2011-01-30 09:00:37

标签: ios map uiscrollview catiledlayer

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

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

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

问题是,当我在上下文中没有绘制任何内容时,视图的该部分显示为空白区块。并且预期的行为是显示来自先前缩放级别的放大缩放的平铺视图。

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

4 个答案:

答案 0 :(得分:1)

我这样做,阻止线程,直到下载了磁贴。性能良好,运​​行顺畅。我正在使用队列来存储每个磁贴请求,因此我也可以取消那些不再有用的磁贴请求。

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

听起来对你好吗?它对我有用!

答案 1 :(得分:0)

只要有数据,就必须为tile设置setNeedsDisplayInRect :.你必须忍受它是空白的,直到瓷砖可用,因为你无法影响CATiledLayer正在创建哪些瓷砖。

答案 2 :(得分:0)

您的CATiledLayer应该按照您的预期从之前的缩放级别提供此图块。您为平铺图层设置的levelsOfDetaillevelsOfDetailBias是什么?

答案 3 :(得分:0)

你必须调用setNeedsDisplay或setNeedsDisplayInRect:但问题是如果你调用它然后它会重绘scrollView中的每个tile。所以尝试使用UIView的子类而不是CATiledLayer子类,并实现像这样的TiledView(UIView的子类),

+ (Class) layerClass {
    return [CATiledLayer class];
}

-(void)drawRect:(CGRect)r {
    CGRect tile = r;
    int x = tile.origin.x/TILESIZE;
    int y = tile.origin.y/TILESIZE;
    NSString *tileName = [NSString stringWithFormat:@"Shed_1000_%i_%i", x, y];
    NSString *path =
        [[NSBundle mainBundle] pathForResource:tileName ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:path];
    [image drawAtPoint:tile.origin];
    // uncomment the following to see the tile boundaries
    /*
    UIBezierPath* bp = [UIBezierPath bezierPathWithRect: r];
    [[UIColor whiteColor] setStroke];
    [bp stroke];
    */
}

for 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];