【问题标题】:Using CATiledLayer's drawLayer:inContext:使用 CATiledLayer 的 drawLayer:inContext:
【发布时间】:2011-01-30 09:00:36
【问题描述】:

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

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

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

问题是,当我不在上下文中绘制任何东西时,视图的那部分显示为空白图块。并且预期的行为是从以前的缩放级别显示放大的缩放平铺视图。

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

【问题讨论】:

    标签: ios map uiscrollview catiledlayer


    【解决方案1】:

    您必须在获得数据后立即为该图块设置NeedsDisplayInRect:。在瓷砖可用之前,您必须忍受它是空白的,因为您无法影响 CATiledLayer 正在创建哪些瓷砖。

    【讨论】:

      【解决方案2】:

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

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

      你觉得好听吗?它对我有用!

      【讨论】:

      • 这实际上是一个答案还是只是对问题的评论?
      • 好吧,我认为这是一个答案,因为我遇到了同样的问题并且我解决了它。我没有代码可以在这里显示(我还在工作),但解决方法是有效的。也许我没有正确解释它。我的意思是我确实在等待请求,所以我总是在上下文中画一些东西。如果他意识到性能影响,我的经验是这根本不会造成影响。但是您必须缓存这些图块,以避免重复请求。如果您需要代码,我可以在今晚或明天提供。
      【解决方案3】:

      您的CATiledLayer 应该按照您的预期从之前的缩放级别提供此磁贴。您为平铺层设置的levelsOfDetail 和levelsOfDetailBias 是什么?

      【讨论】:

        【解决方案4】:

        你必须调用 setNeedsDisplay 或 setNeedsDisplayInRect: 但问题是如果你调用它,那么它将重绘滚动视图中的每个图块。所以尝试使用 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];
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多