首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS 13.2 MKTileOverlay偶尔不会呈现

iOS 13.2 MKTileOverlay偶尔不会呈现
EN

Stack Overflow用户
提问于 2019-12-30 11:31:06
回答 2查看 596关注 0票数 2

我有一个问题,在iOS 13.2 (可能也是从iOS 13),使用MKTileOverlay加载离线地图瓦片有时无法渲染,留下瓦片空白,MKTileOverlay的子类似乎没有任何问题,因为它在iOS 12和更低的版本中工作得很好。我有2个MKTileOverlay类(一个添加网格和一个加载地图瓦片文件,默认MKTileOverlay),两者都不能加载到默认MKTileOverlayRenderer的空白瓦片上,其他覆盖看起来很好。

如果我转到主屏幕并返回到应用程序,导致磁贴重新加载,问题似乎就会自行解决。这是iOS MapKit本身的错误吗?有谁对此有临时的解决方案吗?谢谢。

添加overlay的代码:

代码语言:javascript
复制
let overlay = MKTileOverlay(urlTemplate: urlTemplate)
overlay.canReplaceMapContent = true
overlay.maximumZ = 19
mapView.insertOverlay(overlay, at: 0, level: .aboveLabels)

渲染器:

代码语言:javascript
复制
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKTileOverlay {
        let renderer = MKTileOverlayRenderer(tileOverlay: overlay as! MKTileOverlay)
        return renderer
    }

    return MKOverlayRenderer()
}

EN

回答 2

Stack Overflow用户

发布于 2020-02-16 07:03:02

正如我在对原始问题的评论中指出的那样,我也遇到了同样的问题,但现在它基本上已经解决了,所以我想我应该发布对我有效的方法。

对于我来说,问题出现在以下方法中

代码语言:javascript
复制
- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData * __nullable tileData, NSError * __nullable error))result{

其中自定义磁贴将无法加载,即使它被呈现似乎是有效的NSData。

我发现,如果我使用jpegs而不是png来定制磁贴,问题就会减少,但只有当我改变了处理磁贴数据的方式时,问题才基本消失。(我在很大程度上是因为我仍然偶尔会得到卸载的磁贴,但我想说的是,它的频率比以前减少了100倍)。

以下方法是我的Xamarin.iOS实现,但您应该能够看到Swift或Objective C的原理。

关键在于创建NSData的方式的不同。我没有调用UrlForTilePath方法,而是从磁贴路径创建一个UIImage,然后使用UIImageJPEGRepresentation (C#中的AsJPEG)创建NSData。

代码语言:javascript
复制
   public override void LoadTileAtPath(MKTileOverlayPath path, MKTileOverlayLoadTileCompletionHandler result)
    {
        //I was using this prior to ios 13.2

        //NSUrl url = this.URLForTilePath(path);
        //NSData tileData = NSData.FromFile(url.AbsoluteString);
        //result(tileData, null);

        //Now I use this

        String folderPath = "tiles/" + path.Z + "/" + path.X + "/";
        String tilePath = NSBundle.MainBundle.PathForResource(path.Y.ToString(), "jpg", folderPath);
        String blankPath = NSBundle.MainBundle.PathForResource("tile", "jpg");

        try
        {
            //does the file exist?
            UIImage tile;
            if (File.Exists(tilePath))
            {
                tile = UIImage.FromFile(tilePath);
                if (tile == null)
                {
                    Console.WriteLine("Error Loading " + path.Z + " " + path.Y + " " + path.X);
                    //This may be redundant, as I'm not getting any errors here, even when the tile doesn't display
                }
            }
            else
            {
                tile = UIImage.FromFile(blankPath);
            }

            NSData tileData = tile.AsJPEG();
            result(tileData, null);
        }
        catch (Exception ex)
        {

        }
    }
票数 2
EN

Stack Overflow用户

发布于 2020-02-19 17:32:25

这显然是一个MapKit问题/错误。

从2020年12月9日起,我还开了一张回馈票。

这个问题的根源并不是很确定。

MapKit和特别是MKTileOverlay对于像PNG 24bit这样的“笨重”的磁贴总是有一些问题。当MKTileOverlay使用PNG (重型瓦片)时,瓦片有时会闪烁,尤其是在宽屏幕(iPad pro等)的情况下,地图会不断重新加载。

因此,由于JPEG平铺通常比PNG轻,因此JPEG可以作为一种解决办法。

但是,这个新的iOS 13.2+问题是不一样的!不渲染随机平铺。如果你移除并读取MKTileOverlay或者调用MKTileOverlayRenderer的reloadData方法,丢失的tiles将被渲染,并且它将被other随机tiles that丢失。

这个问题的真正解决方案是打开一个反馈工单:https://feedbackassistant.apple.com

JPEG :我刚刚试着用85%的替换我的8位,这个非常简单的MKTileOverlay项目样本我已经在我的工单里发给了苹果。同样的问题。没有改进。

编辑2:将NSData加载到UIImage中,然后使用UIImageRepresentationJPEG似乎可以做到这一点……丑陋的。

代码语言:javascript
复制
- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData * _Nullable, NSError * _Nullable))result
{
    NSString *tilePath = [self PATHForTilePath:path];
    NSData *data = nil;

    if (![[NSFileManager defaultManager] fileExistsAtPath:tilePath])
    {
        NSLog(@"Z%ld/%ld/%ld does not exist!", path.z, path.x, path.y);
    }
    else
    {
        NSLog(@"Z%ld/%ld/%ld exist", path.z, path.x, path.y);

        UIImage *image = [UIImage imageWithContentsOfFile:tilePath];
        data = UIImageJPEGRepresentation(image, 0.8);
        // Instead of: data = [NSData dataWithContentsOfFile:tilePath];

        if (data == nil)
        {
            NSLog(@"Error!!! Unable to read an existing file!");
        }
    }

    dispatch_async(dispatch_get_main_queue(), ^{
        result(data, nil);
    });
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59525403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档