Использование drawLayer CATiledLayer: inContext: - PullRequest
1 голос
/ 30 января 2011

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

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

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

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

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

Ответы [ 4 ]

1 голос
/ 10 октября 2012

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

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

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

0 голосов
/ 20 марта 2013

Вы должны вызвать 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];
0 голосов
/ 03 февраля 2012

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

0 голосов
/ 20 июня 2011

Вы должны установитьNeedsDisplayInRect: для плитки, как только у вас есть данные.Вы должны оставаться пустыми до тех пор, пока плитка не станет доступной, потому что вы не можете повлиять на то, какие плитки создает CATiledLayer.

...