我有一个问题,在iOS 13.2 (可能也是从iOS 13),使用MKTileOverlay加载离线地图瓦片有时无法渲染,留下瓦片空白,MKTileOverlay的子类似乎没有任何问题,因为它在iOS 12和更低的版本中工作得很好。我有2个MKTileOverlay类(一个添加网格和一个加载地图瓦片文件,默认MKTileOverlay),两者都不能加载到默认MKTileOverlayRenderer的空白瓦片上,其他覆盖看起来很好。
如果我转到主屏幕并返回到应用程序,导致磁贴重新加载,问题似乎就会自行解决。这是iOS MapKit本身的错误吗?有谁对此有临时的解决方案吗?谢谢。
添加overlay的代码:
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()
}

发布于 2020-02-16 07:03:02
正如我在对原始问题的评论中指出的那样,我也遇到了同样的问题,但现在它基本上已经解决了,所以我想我应该发布对我有效的方法。
对于我来说,问题出现在以下方法中
- (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。
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)
{
}
}发布于 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似乎可以做到这一点……丑陋的。
- (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);
});
}https://stackoverflow.com/questions/59525403
复制相似问题