2011-01-30 6 views
1

Я пытаюсь реализовать свой собственный движок карты, используя CATiledLayer + UIScrollView.Использование drawLayer для CATiledLayer: inContext:

В методе drawLayer:inContext: моей реализации, если у меня есть определенное изображение плитки, необходимое для текущего ограничивающего прямоугольника, я сразу рисую его в контексте.

Однако, когда у меня нет одной доступной в структуре данных локального кэша, изображение плитки асинхронно запрашивается/загружается с сервера плитки и не рисует ничего в контексте.

Проблема заключается в том, что, когда я не рисую что-либо в контексте, эта часть представления отображается как пустая плитка. И ожидаемое поведение заключается в том, чтобы показать масштабированный масштабный вид плитки с предыдущего уровня масштабирования.

Если вы, ребята, столкнулись с какой-либо подобной проблемой и нашли какое-либо решение для этого, пожалуйста, дайте мне знать.

ответ

0

Вы должны установитьNeedsDisplayInRect: для плитки, как только у вас есть данные. Вы должны жить с этим пустым, пока плитка не будет доступна, потому что у вас нет возможности повлиять на то, какие плитки CatiledLayer создаются.

0

Ваш CATiledLayer должен предоставить эту плитку с предыдущего уровня масштабирования, как вы ожидаете. Каковы ваши levelsOfDetail и levelsOfDetailBias для плиточного слоя?

1

Я делаю то же самое, блокируя поток до тех пор, пока плитка не будет загружена. Производительность хорошая, она работает гладко. Я использую очередь для хранения каждого запроса на черепицу, поэтому я также могу отменить те запросы, которые больше не нужны.

Для этого используйте блокировку, чтобы остановить поток сразу после запуска запроса асинхронной печати и разблокировать его, как только у вас будет кеш-память.

Звучит так хорошо для вас? Это сработало для меня!

+1

это на самом деле ответ или просто комментарий по этому вопросу? – thecoshman

+0

Ну, я думаю, это ответ, так как у меня была та же проблема, и я решил это. У меня нет кода для показа здесь (я все еще на работе), но обходной путь действителен. Возможно, я не объяснил это должным образом. Я имею в виду, что я жду запроса, поэтому я всегда рисую что-то в этом контексте. Если он знает о влиянии на производительность, мой опыт в том, что это вообще не влияет. Но вы должны кэшировать эти фрагменты, чтобы избежать повторения запросов. Если вам нужен код, я могу предоставить его сегодня или завтра. – khose

0

Вы должны вызвать setNeedsDisplay или setNeedsDisplayInRect: Но проблема в том, что если вы вызываете это, тогда он будет перерисовывать каждую плиту в scrollView. Так попробуйте использовать подкласс 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]; 
    */ 
} 

и

для 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];