iOS 13.2 MKTileOverlay偶尔获胜';不渲染

iOS 13.2 MKTileOverlay偶尔获胜';不渲染,ios,swift,mapkit,Ios,Swift,Mapkit,我遇到了一个问题,在iOS 13.2中(可能也来自iOS 13),使用MKTileOverlay加载脱机地图磁贴时有时无法渲染,将磁贴留空,因为MKTileOverlay的子类在iOS 12及以下版本中运行良好,因此似乎根本没有问题。我有2个MKTileOverlay类(1个添加网格,1个加载贴图平铺文件,默认值MKTileOverlay),这两个类都无法使用默认值MKTileOverlay渲染器加载到空白平铺上,其他覆盖看起来很好 如果我转到主屏幕并返回应用程序,导致磁砖重新加载,问题似乎会自

我遇到了一个问题,在iOS 13.2中(可能也来自iOS 13),使用
MKTileOverlay
加载脱机地图磁贴时有时无法渲染,将磁贴留空,因为
MKTileOverlay
的子类在iOS 12及以下版本中运行良好,因此似乎根本没有问题。我有2个
MKTileOverlay
类(1个添加网格,1个加载贴图平铺文件,默认值
MKTileOverlay
),这两个类都无法使用默认值
MKTileOverlay渲染器加载到空白平铺上,其他覆盖看起来很好

如果我转到主屏幕并返回应用程序,导致磁砖重新加载,问题似乎会自行解决。这是iOS MapKit本身的bug吗?有人对此有临时解决办法吗?多谢各位

用于添加覆盖的代码:

let overlay = MKTileOverlay(urlTemplate: urlTemplate)
overlay.canReplaceMapContent = true
overlay.maximumZ = 19
mapView.insertOverlay(overlay, at: 0, level: .aboveLabels)
渲染器:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKTileOverlay {
        let renderer = MKTileOverlayRenderer(tileOverlay: overlay as! MKTileOverlay)
        return renderer
    }

    return MKOverlayRenderer()
}

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

我的问题发生在以下方法中

- (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData * __nullable tileData, NSError * __nullable error))result{
其中,即使显示的是有效的NSData,自定义磁贴也无法加载

我发现,如果我使用JPEG而不是PNG来处理我的自定义分幅,问题就会减少,但只有当我改变处理分幅数据的方式时,问题才基本消失。(我主要是因为我仍然偶尔会得到未加载的瓷砖,但我会说这比我以前得到它们的次数少了100倍)

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

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

   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)
        {

        }
    }

这显然是一个MapKit问题/bug

自2020年12月9日起,我还打开了一张反馈单

这个问题的根源还不是很清楚

MapKit和特别是MKTileOverlay在使用PNG 24位这样的“重”瓷砖时总是有一些问题。当MKTileOverlay使用PNG(重瓷砖)时,瓷砖有时会闪烁,地图会不断重新加载,尤其是在宽屏幕(iPad pro等)下

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

但是,这个新的iOS 13.2+版本是不一样的!不渲染随机平铺。如果删除并读取MKTileOverlay或调用MKTileOverlayRenderer的reloadData方法,则将渲染缺失的分幅,并且它将是其他缺失的随机分幅

问题的真正解决方案是打开反馈单:

编辑:我刚刚试着用85%的JPEG替换我的8位PNG,这个非常简单的MKTileOverlay项目示例是我在我的票证中发送给苹果的。同样的问题。。。没有改善

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

- (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);
    });
}

你找到解决办法了吗?我在Xamarin.iOS中使用MapKit的一个长期应用程序中遇到了完全相同的问题。到了我把它从商店里拿出来的时候,苹果似乎在13.2左右引入了很多问题。在空白瓦片的情况下,我跟踪到了MKOFLADILTERDENDER,这是无法加载图像的,即使在提供了有效的数据时。@ PaldJoad不幸的是,我不得不在<代码> MavVIEW FrimeSeReDrimeM映射(MavVIEW:FulyFrave:)/<代码>中调用一个不太好的解决方案:“代码< > ReDeReal.RealDeDATA())/>代码>手动。它将继续闪烁,但它应该消除空白砖重新加载感谢您的输入,我已经尝试了同样的事情,但它仍然发生在我很频繁:(尤其是在有很多注释的地方。可能是因为我还在使用png图像,我只在
loadTile
期间将其转换为jpeg,可能不会有任何效果。我确实注意到,当我将叠加和注释放在一起时,情况会更糟,但在我的情况下,这种情况并不经常发生。我确实向苹果提交了一份反馈报告。非常相似。)对于上述方法,我也没有看到任何改进,在我的地图中,有些地方有大约50针,如果我缩小,它总是导致空白平铺…仍然唯一的修复方法是,一旦用户停止移动地图,继续重新加载。