2013-02-01 43 views
2

我有興趣打印一些不屬於視圖層次結構的MKMapView,並且只有在用戶點擊打印時纔會創建。Offscreen iOS 6 MKMapViews和UIViewPrintFormatter - 讓他們及時渲染?

看來,下面的東西都是真實的:

  1. 屏外MKMapViews不渲染的。
  2. 打印一個MKMapView打印呈現,但它目前是。

因此,似乎要打印我的地圖視圖,我需要讓他們進入視圖層次結構。幸運的是,從實驗看來,我可以在屏幕上放置一堆地圖視圖,它們仍然會呈現。

我的主要問題是我如何知道他們已經呈現?如果在將地圖視圖放入視圖層次結構中後立即將打印命令關閉,它們將打印部分渲染,並且缺少位,如下所示。我想等到他們完成加載後,再運行打印作業。 (更好的是,如果他們可以在屏幕上打印紙張時在後臺加載,然後在打印完成之後給用戶一個進度條,直到地圖加載完成。)

(下圖:圖像。顯示如果打印部分裝載的地圖視圖會發生什麼)

Printout

我二次的問題是:有沒有更好的方法來打印多個地圖的看法?將所有內容都放到視圖層次結構中並不是很好 - 它限制了我可以使用的最大大小,這意味着我有許多笨拙的代碼來處理子視圖。

回答

2

你應該在你的地圖視圖設置一個委託(MKMapViewDelegate)和實施mapViewDidFinishLoadingMap:,在地圖視圖已完成加載必要的瓦片將被調用。

+0

我怎麼錯過那一個!從谷歌搜索,它看起來像它沒有被調用,如果地圖有緩存瓷磚,但它應該與'willStartLoadingMap'調用平衡。 –

+0

其實,我很擔心這個問題,希望我不會碰到它:http://stackoverflow.com/questions/12598569/mkmap-works-incorrect-in-ios6 –

+1

@AmyWorrall,我還沒有遇到了這個特定的問題,但是我被「UIWebView」可能存在的類似問題所困擾。在Apple的術語中,Web視圖的回調告訴你它已經完成*加載*並不意味着它已經完成*渲染*。在加載回調之後,我可以在一秒之內看到渲染完成。在一個應用程序中,我必須使用JavaScript hack來檢測渲染實際完成時的情況,但這與此無關。無論如何,只是想澄清他們的術語可能是什麼(假設它是一致的)。 – Nate

0

當地圖視圖不一定在屏幕上可見時,我遇到了將MKMapView渲染爲圖像的類似問題。我發現以下解決方案適合我。我希望這可以幫助別人。基本上,它確保地圖有一個窗口。在ios6.0中,您需要給它一個窗口才能讓它加載地圖,然後在完成加載後,您在渲染之前等待一會兒,以便讓tile有機會加載。在ios 5.0中,您不需要等待didfinishload,只需確保地圖在渲染功能中有一個窗口,並且這些圖塊將可見。

{ 
     if ([@"5.9.9" compare:[UIDevice currentDevice].systemVersion options:NSNumericSearch] == NSOrderedAscending) { 
      // actualVersion is lower than the requiredVersion 
      self.oldSuperview = nil; 
      if (self.map.window == nil) { 
     self.oldSuperview = self.map.superview; 
       [[[[UIApplication sharedApplication] delegate] window] insertSubview:self.map atIndex:0]; 
      } 
     } else { 
     [self performSelector:@selector(renderMap) withObject:nil afterDelay:0.10]; 
    } 

} 

-(void) renderMap { 

    //map will only render tiles if it has a window, so we need to add it to 
    //the main window if it does not have a window. 

    if ([@"5.9.9" compare:[UIDevice currentDevice].systemVersion options:NSNumericSearch] != NSOrderedAscending) { 
     if (self.map.window == nil) { 
      self.oldSuperview = self.map.superview; 
      [[[[UIApplication sharedApplication] delegate] window] addSubview:self.map]; 
     } 
    } 


    // Generate the image centred 
    UIGraphicsBeginImageContextWithOptions(self.map.bounds.size, NO, 0.0); 

    [self.map.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 


    // Save the image here 


    if ([@"5.9.9" compare:[UIDevice currentDevice].systemVersion options:NSNumericSearch] != NSOrderedAscending) { 

     if (self.oldSuperview) { 
      [self.map removeFromSuperview]; 
      [self.oldSuperview addSubview:self.map]; 
      self.oldSuperview = nil; 
     } 

    } 

} 

} 



-(void) cleanMap { 
     if (self.map.superview == [[[UIApplication sharedApplication] delegate] window]) { 

      if (oldSuperview) { 
       [oldSuperview addSubview:self.map]; 
       self.oldSuperview = nil; 
      } 
     } 
} 
-(void) mapViewDidFinishLoadingMap:(MKMapView *)mapView { 

if ([@"5.9.9" compare:[UIDevice currentDevice].systemVersion options:NSNumericSearch] == NSOrderedAscending) { 
    if (oldSuperview) { 

     [self performSelector:@selector(renderMap) withObject:nil afterDelay:1.10]; 
     [self performSelector:@selector(cleanMap) withObject:nil afterDelay:1.41]; 
    } else { 
     [self renderMap]; 
    } 
} else { 
    [self renderMap]; 
} 

}