I'm attempting to save a thumbnail of a mapview when a user taps save when an annotation has been selected. The problem occurs when the user has not zoomed in on that annotation yet, so the close zoom level has not been loaded.
当用户在选择注释时点击保存时,我正在尝试保存mapview的缩略图。当用户尚未放大该注释时,会出现此问题,因此尚未加载关闭缩放级别。
This is what I'm doing after the user taps save:
这是用户点击保存后我正在做的事情:
- Set a bool "saving" to true
- 将bool“save”设置为true
- Center and zoom in on the annotation (no animation)
- 居中并放大注释(无动画)
- When the mapViewDidFinishLoadingMap delegate method gets called, and if saving is true:
- 调用mapViewDidFinishLoadingMap委托方法时,如果save为true:
- Create an UIImage out of the view, and save it. Dismiss modal view.
- 从视图中创建UIImage并保存。关闭模态视图。
However when the image is saved, and the view is dismissed the result image saved actually has not finished loading, as I still see an unloaded map with gridlines as shown below:
但是,当保存图像并且视图被取消时,实际保存的结果图像实际上还没有完成加载,因为我仍然看到带有网格线的卸载地图,如下所示:
My question is, how can I ensure the map is finished loading AND finished displaying before I save this thumbnail?
我的问题是,在保存此缩略图之前,如何确保地图已完成加载并完成显示?
3 个解决方案
#1
17
Update: iOS7 has a new delegate which may have fixed this problem. I have not confirmed one way or the other yet.
更新:iOS7有一个新的委托可能已修复此问题。我还没有证实这种或那种方式。
- (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
Pre iOS6 support:
预iOS6支持:
mapViewDidFinishLoadingMap
: appears to be unreliable. I notice that it is sometimes not called at all, especially if the map tiles are already cached, and sometimes it is called multiple times.
mapViewDidFinishLoadingMap:似乎不可靠。我注意到它有时根本不被调用,特别是如果地图图块已经被缓存,有时它被多次调用。
I notice that when it is called multiple times the last call will render correctly. So I think you can get this to work if you set up a 2 second timer after the user taps save. Disable interactions so that nothing else can happen, and enable user interactions when the timer goes.
我注意到,当它被多次调用时,最后一次调用将正确呈现。因此,如果您在用户点击保存后设置2秒计时器,我认为您可以使用此功能。禁用交互以便不会发生任何其他情况,并在计时器启动时启用用户交互。
If mapViewDidFinishLoadingMap
gets called reset the timer again for 2 seconds in the future. When the timer finally goes off, get the snapshot of the map and it should be correct.
如果调用mapViewDidFinishLoadingMap将来再次重置计时器2秒钟。当计时器最终关闭时,获取地图的快照,它应该是正确的。
You will also want to consider the other callbacks such as mapViewDidFailLoadingMap
. Also test this on a noisy connection, since 2 seconds may not be long enough if it takes a long time to fetch the tiles.
您还需要考虑其他回调,例如mapViewDidFailLoadingMap。还要在嘈杂的连接上测试它,因为如果需要很长时间来获取磁贴,2秒可能不够长。
- (void)restartTimer
{
[self.finishLoadingTimer invalidate];
self.finishLoadingTimer = [NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(mapLoadingIsFinished)
userInfo:nil
repeats:NO];
}
- (void)userClickedSave
{
assert(self.saving == NO);
if (self.saving == NO) {
self.saving = YES;
assert(self.finishLoadingTimer == nil);
self.view.userInteractionEnabled = NO;
[self restartTimer];
}
}
- (void)mapLoadingIsFinished
{
self.finishLoadingTimer = nil;
[self doSnapshotSequence];
self.saving = NO;
self.view.userInteractionEnabled = YES;
}
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
if (self.saving) {
[self restartTimer];
}
}
#2
5
If developing for iOS7 the best delegate to use is: mapViewDidFinishRenderingMap:fullyRendered:
如果为iOS7开发,最好使用的委托是:mapViewDidFinishRenderingMap:fullyRendered:
mapViewDidFinishRenderingMap:fullyRendered
mapViewDidFinishRenderingMap:fullyRendered
#3
0
Are you sure the area where you are taking the screenshot has the Zoom Level supported which you are applying. For example, in US zoom level support is higher, you can zoom in to the maximum detail, while in Asia may be a high zoom level might not be supported.
您确定要截取屏幕截图的区域是否支持您正在应用的缩放级别。例如,在美国缩放级别支持较高时,您可以放大到最大细节,而在亚洲可能不支持高缩放级别。
#1
17
Update: iOS7 has a new delegate which may have fixed this problem. I have not confirmed one way or the other yet.
更新:iOS7有一个新的委托可能已修复此问题。我还没有证实这种或那种方式。
- (void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
Pre iOS6 support:
预iOS6支持:
mapViewDidFinishLoadingMap
: appears to be unreliable. I notice that it is sometimes not called at all, especially if the map tiles are already cached, and sometimes it is called multiple times.
mapViewDidFinishLoadingMap:似乎不可靠。我注意到它有时根本不被调用,特别是如果地图图块已经被缓存,有时它被多次调用。
I notice that when it is called multiple times the last call will render correctly. So I think you can get this to work if you set up a 2 second timer after the user taps save. Disable interactions so that nothing else can happen, and enable user interactions when the timer goes.
我注意到,当它被多次调用时,最后一次调用将正确呈现。因此,如果您在用户点击保存后设置2秒计时器,我认为您可以使用此功能。禁用交互以便不会发生任何其他情况,并在计时器启动时启用用户交互。
If mapViewDidFinishLoadingMap
gets called reset the timer again for 2 seconds in the future. When the timer finally goes off, get the snapshot of the map and it should be correct.
如果调用mapViewDidFinishLoadingMap将来再次重置计时器2秒钟。当计时器最终关闭时,获取地图的快照,它应该是正确的。
You will also want to consider the other callbacks such as mapViewDidFailLoadingMap
. Also test this on a noisy connection, since 2 seconds may not be long enough if it takes a long time to fetch the tiles.
您还需要考虑其他回调,例如mapViewDidFailLoadingMap。还要在嘈杂的连接上测试它,因为如果需要很长时间来获取磁贴,2秒可能不够长。
- (void)restartTimer
{
[self.finishLoadingTimer invalidate];
self.finishLoadingTimer = [NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(mapLoadingIsFinished)
userInfo:nil
repeats:NO];
}
- (void)userClickedSave
{
assert(self.saving == NO);
if (self.saving == NO) {
self.saving = YES;
assert(self.finishLoadingTimer == nil);
self.view.userInteractionEnabled = NO;
[self restartTimer];
}
}
- (void)mapLoadingIsFinished
{
self.finishLoadingTimer = nil;
[self doSnapshotSequence];
self.saving = NO;
self.view.userInteractionEnabled = YES;
}
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
if (self.saving) {
[self restartTimer];
}
}
#2
5
If developing for iOS7 the best delegate to use is: mapViewDidFinishRenderingMap:fullyRendered:
如果为iOS7开发,最好使用的委托是:mapViewDidFinishRenderingMap:fullyRendered:
mapViewDidFinishRenderingMap:fullyRendered
mapViewDidFinishRenderingMap:fullyRendered
#3
0
Are you sure the area where you are taking the screenshot has the Zoom Level supported which you are applying. For example, in US zoom level support is higher, you can zoom in to the maximum detail, while in Asia may be a high zoom level might not be supported.
您确定要截取屏幕截图的区域是否支持您正在应用的缩放级别。例如,在美国缩放级别支持较高时,您可以放大到最大细节,而在亚洲可能不支持高缩放级别。