2011-01-30 91 views
1

我試圖通過使用CATiledLayer + UIScrollView來實現我自己的地圖引擎。使用CATiledLayer的drawLayer:inContext:

drawLayer:inContext:我的實現方法中,如果我有當前邊界框所需的某個圖像,我立即在上下文中繪製它。

但是,當我在本地緩存數據結構中沒有可用的映像時,映像映像將從映像服務器異步請求/下載,並且不會在上下文中繪製任何內容。

問題是,當我沒有在上下文中繪製任何東西時,視圖的該部分顯示爲空白圖塊。預期的行爲是顯示前一縮放級別的放大縮放平鋪視圖。

如果你們遇到任何類似的問題,並找到任何解決方案,請讓我知道。

回答

0

只要有數據,您就必須爲瓦片設置NeedNeedsDisplayInRect:。您必須忍受它一直處於空白狀態,直到該圖塊可用,因爲您無法影響CATiledLayer創建的圖塊。

0

您的CATiledLayer應該像您期望的那樣提供來自之前縮放級別的此圖塊。什麼是你的levelsOfDetaillevelsOfDetailBias設置爲平鋪層?

1

我這樣做,阻塞線程,直到瓦片已被下載。表現很好,運行平穩。我使用一個隊列來存儲每個tile請求,所以我也可以取消那些不再有用的tile請求。

要做到這一點,只需在啓動異步切片請求後立即使用鎖定即可停止該線程,並在您緩存切片後立即解鎖該線程。

聽起來對你有好處?它爲我工作!

+1

是這其實回答還是隻是對問題的評論? – thecoshman 2012-10-10 12:42:44

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]; 
    */ 
} 

了滾動,

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