在屏幕外渲染 MKMapView
Render MKMapView offscreen
我正在尝试将 MKMapView
渲染为 UIImage
,但不在屏幕上显示。我初始化地图:
let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))
mapView.delegate = self
let region = MKCoordinateRegionMakeWithDistance(location.coordinate(), 1000, 1000)
mapView.setRegion(region, animated: false)
我也实现了MKMapKitDelegate
的方法mapViewDidFinishLoadingMap()
。此方法永远不会被调用,除非我将地图添加到视图层次结构并且使其可见。这意味着将其 alpha
设置为 0,或将 isHidden
设置为 true
不起作用(在这种情况下地图不会加载)。帮忙?
你能说说你隐藏的目的是什么吗?如果您的图像不可见,地图将不会加载数据,这就是为什么它的委托没有被调用的原因,正如苹果文档中提到的那样,请参阅下面的描述。它说在你的情况下加载当前请求时将调用它我认为地图不可见因此它的请求未加载并且当你使其可见时请求被加载因此你可以看到。
This method is called when the map tiles associated with the current request have been loaded. Map tiles are requested when a new visible area is scrolled into view and tiles are not already available. Map tiles may also be requested for portions of the map that are not currently visible. For example, the map view may load tiles immediately surrounding the currently visible area as needed to handle small pans by the user.
https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452291-mapviewdidfinishloadingmap
显然,MKMapView
仅加载地图的可见图块,因此您要离线渲染的 mapView
必须是“可见的”。
据我所知,一个视图是“可见的”,如果它的 window
属性 被设置,即不是 nil
(参见 progrmr
的回答 here ).
因此,一种可能性是设置一个额外的 UIWindow
,将您的 mapView
作为根视图。在这种情况下,您的 mapView
的 window
属性 已设置,我相信 mapView
会加载所需的图块,以便可以渲染,即使额外的 UIWindow
不可见.
这显然是由 pageViewController
完成的,请参阅上面 link 中 evanflash
的评论。
好的,这是我自己的解决方案。
实施MKMapViewDelegate
方法mapViewDidFinishRenderingMap(_ mapView:, fullyRendered:)
。请务必使用此方法而不是 mapViewDidFinishLoadingMap(_ mapView:)
!
这是古怪的部分。将您的地图视图添加到现有的可见视图(我使用视图控制器自己的视图),并将其放置在屏幕外,只显示一个像素。这很重要,因为如果地图没有可见像素,它就不会呈现。例如:
let width = 1000
let height = 1000
let mapView = MKMapView(frame: CGRect(x: -width+1, y: -height+1, width: width, height: height))
view.addSubview(mapView)
没有第 3 步。如果您正确配置地图,将调用 (1) 中提到的委托方法,此时您将拥有完全渲染的地图。
我上周遇到了这个问题,因为我嵌入了 MapView
在 Stackview 中,因此当设置为 hidden
时它会 自动 减少。也许不是你的情况,但你应该为你的 mapView 检查 Size
。
此外,在我用另一个替换 StackView 之前,将 alpha
设置为接近零的值 - 而不是使用 hidden
- 确实有所帮助(未检查为零)。
我正在尝试将 MKMapView
渲染为 UIImage
,但不在屏幕上显示。我初始化地图:
let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))
mapView.delegate = self
let region = MKCoordinateRegionMakeWithDistance(location.coordinate(), 1000, 1000)
mapView.setRegion(region, animated: false)
我也实现了MKMapKitDelegate
的方法mapViewDidFinishLoadingMap()
。此方法永远不会被调用,除非我将地图添加到视图层次结构并且使其可见。这意味着将其 alpha
设置为 0,或将 isHidden
设置为 true
不起作用(在这种情况下地图不会加载)。帮忙?
你能说说你隐藏的目的是什么吗?如果您的图像不可见,地图将不会加载数据,这就是为什么它的委托没有被调用的原因,正如苹果文档中提到的那样,请参阅下面的描述。它说在你的情况下加载当前请求时将调用它我认为地图不可见因此它的请求未加载并且当你使其可见时请求被加载因此你可以看到。
This method is called when the map tiles associated with the current request have been loaded. Map tiles are requested when a new visible area is scrolled into view and tiles are not already available. Map tiles may also be requested for portions of the map that are not currently visible. For example, the map view may load tiles immediately surrounding the currently visible area as needed to handle small pans by the user.
https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452291-mapviewdidfinishloadingmap
显然,MKMapView
仅加载地图的可见图块,因此您要离线渲染的 mapView
必须是“可见的”。
据我所知,一个视图是“可见的”,如果它的 window
属性 被设置,即不是 nil
(参见 progrmr
的回答 here ).
因此,一种可能性是设置一个额外的 UIWindow
,将您的 mapView
作为根视图。在这种情况下,您的 mapView
的 window
属性 已设置,我相信 mapView
会加载所需的图块,以便可以渲染,即使额外的 UIWindow
不可见.
这显然是由 pageViewController
完成的,请参阅上面 link 中 evanflash
的评论。
好的,这是我自己的解决方案。
实施
MKMapViewDelegate
方法mapViewDidFinishRenderingMap(_ mapView:, fullyRendered:)
。请务必使用此方法而不是mapViewDidFinishLoadingMap(_ mapView:)
!这是古怪的部分。将您的地图视图添加到现有的可见视图(我使用视图控制器自己的视图),并将其放置在屏幕外,只显示一个像素。这很重要,因为如果地图没有可见像素,它就不会呈现。例如:
let width = 1000 let height = 1000 let mapView = MKMapView(frame: CGRect(x: -width+1, y: -height+1, width: width, height: height)) view.addSubview(mapView)
没有第 3 步。如果您正确配置地图,将调用 (1) 中提到的委托方法,此时您将拥有完全渲染的地图。
我上周遇到了这个问题,因为我嵌入了 MapView
在 Stackview 中,因此当设置为 hidden
时它会 自动 减少。也许不是你的情况,但你应该为你的 mapView 检查 Size
。
此外,在我用另一个替换 StackView 之前,将 alpha
设置为接近零的值 - 而不是使用 hidden
- 确实有所帮助(未检查为零)。