Render MKMapView за кадром

Я пытаюсь сделать 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 не работает (карта не загружается в этом случае). Помогите?

4 ответа

Решение

ОК, вот мое собственное решение.

  1. Реализовать MKMapViewDelegate метод mapViewDidFinishRenderingMap(_ mapView:, fullyRendered:), Обязательно используйте этот метод вместо mapViewDidFinishLoadingMap(_ mapView:)!

  2. Вот дурацкая часть. Добавьте ваш вид карты в существующий и видимый вид (я использовал собственный вид контроллера представления) и поместите его за экран, показывая только один пиксель. Это важно, поскольку, если на карте нет видимых пикселей, она не будет отображаться. Например:

    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. Нет шага 3. Если вы правильно настроите карту, будет вызван метод делегата, упомянутый в (1), и в этот момент у вас будет полностью отрендеренная карта.

По-видимому, MKMapView загружает только видимые фрагменты карты, поэтому mapView то, что вы хотите визуализировать в автономном режиме, должно быть "видимым".
Насколько я знаю, вид "виден", если его window свойство установлено, т.е. не nil (увидеть progrmr ответ здесь).
Таким образом, может быть возможность установить дополнительный UIWindow это имеет ваш mapView как корневой вид. В этом случае window собственность вашего mapView установлен, и я верю mapView загрузит требуемые тайлы, чтобы их можно было визуализировать, даже если дополнительные UIWindow не видно
Это, по-видимому, аналогичным образом pageViewController см. комментарий evanflash по ссылке выше.

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

Этот метод вызывается, когда плитки карты, связанные с текущим запросом, были загружены. Плитки карты запрашиваются, когда новая видимая область прокручивается в поле зрения, а плитки еще не доступны. Плитки карты могут также запрашиваться для частей карты, которые в данный момент не видны. Например, представление карты может загружать плитки, непосредственно окружающие видимую в данный момент область, по мере необходимости для обработки небольших панелей пользователем.

https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452291-mapviewdidfinishloadingmap

У меня была эта проблема на прошлой неделе, потому что я встроил MapView в Stackview, поэтому он автоматически уменьшался при установке на . Может не ваш случай, но вы должны проверить Sizeдля вас mapView.

Кроме того, прежде чем я заменил StackView другим, настройка alphaк чему-то близкому к нулю - вместо использования hidden-, помогло (нулем не проверял).

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