Неэкранные iOS 6 MKMapViews и UIViewPrintFormatter - заставить их рендериться вовремя?

Я заинтересован в печати некоторых MKMapViews, которые не являются частью иерархии представлений и создаются только тогда, когда пользователь нажимает кнопку Print.

Кажется, что следующие вещи являются правдой:

  1. Внеэкранные MKMapViews не отображаются вообще.
  2. Печать MKMapView печатает это отрендеренный, однако это в настоящее время.

Похоже, что для печати видов на карте мне нужно поместить их в иерархию видов. К счастью, из экспериментов кажется, что я могу разместить на экране несколько видов карт друг перед другом, и они все равно будут визуализироваться.

Мой главный вопрос: откуда мне знать, что они отрисовали? Если я просто отключу команду печати сразу после помещения представлений карты в иерархию представлений, они будут печатать частично обработанные с отсутствующими битами, как показано ниже. Я хотел бы подождать, пока они не загрузятся, а затем запустить задание на печать. (Еще лучше, если они могут загружаться в фоновом режиме, пока лист печати находится на экране, а затем я просто предоставляю пользователю индикатор выполнения после того, как он нажимает кнопку Печать, пока карты не закончат загрузку.)

(Ниже: изображение, показывающее, что происходит, если вы печатаете частично загруженный вид карты.)

Распечатывать

Мой второй вопрос: есть ли лучший способ напечатать несколько видов карты? Вводить все в иерархию представлений не очень хорошо - это ограничивает максимальный размер, который я могу использовать, и это означает, что у меня много неуклюжего кода для манипулирования подпредставлениями.

2 ответа

Решение

Вы должны установить делегат (MKMapViewDelegate) на ваших видах карты и реализовать mapViewDidFinishLoadingMap:, который будет вызываться, когда вид карты завершит загрузку необходимых плиток.

У меня была похожая проблема с рендерингом MKMapView к изображению, когда вид карты не обязательно виден на экране. Я нашел следующее решение работает для меня. Я надеюсь, что это помогает кому-то. По сути, это гарантирует, что на карте есть окно. в ios6.0 вам нужно дать ему окно для загрузки карты, а затем, когда он закончил загрузку, вы немного подождите, прежде чем выполнить рендеринг, чтобы дать плиткам возможность загрузить. в 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];
}

 }
Другие вопросы по тегам