Google Maps iOS SDK анимировать заполнение карты SwiftUI

#swift #swiftui #google-maps-sdk-ios #gmsmapview

#быстрый #swiftui #google-карты-sdk-ios #gmsmapview

Вопрос:

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

В документации GMSMapView.padding говорится, что это может быть выполнено с помощью анимации на основе блоков UIView, но я не уверен, как это будет связано с приложением SwiftUI?

Нижний лист работает нормально, он отображается, когда ожидается, и передает правильное значение заполнения в MapView. Это просто анимация, которую я не могу понять. (Если вам интересно, на нижнем листе используется этот компонент https://github.com/LucasMucGH/BottomSheet )

Буду признателен за любую помощь, спасибо.

Текущий соответствующий код:

 struct MapView: UIViewRepresentable {
  
  var bottomPadding: CGFloat
  private let mapView = GMSMapView(frame: .zero)
  
  func makeUIView(context: Context) -> GMSMapView {
    return mapView
  }

  func updateUIView(_ mapView: GMSMapView, context: Context) {
    mapView.padding = UIEdgeInsets(top: 0, left: 0, bottom: bottomPadding, right: 0)
  }
}

struct ContentView: View {
  
  @State var showBottomSheet: ShowBottomSheet = .hidden
  
  var bottomSheetHeight: CGFloat {
    if showBottomSheet == .visible {
      return showBottomSheet.rawValue
    } else {
      return 0
    }
  }
  
  var body: some View {
        
    GeometryReader { geometry in
      ZStack {
        
        // Map
        MapView(bottomPadding: geometry.size.height * bottomSheetHeight)
        .edgesIgnoringSafeArea(.all)
        .bottomSheet(
          bottomSheetPosition: $showBottomSheet,
          options: [
            .allowContentDrag,
            .swipeToDismiss,
            .noBottomPosition,
            .shadow()
          ],
          content: {}
        )
      }
    }
  }
}

enum ShowBottomSheet: CGFloat, CaseIterable {
    case hidden = 0, visible = 0.5
  }
 

Ответ №1:

Если кому-то интересно, я придумал, как это сделать. Решение оказалось проще, чем я ожидал, оно буквально просто переносит параметр заполнения в закрытие UIView.animate, а затем вызывает его в методе updateUIViewController:

 private func setMapPadding(mapView: GMSMapView) {
    UIView.animate(withDuration: 0.5, delay: 0.18, usingSpringWithDamping: 0.75, initialSpringVelocity: 0) {
      mapView.padding = UIEdgeInsets(top: 0, left: 0, bottom: bottomPadding, right: 0)
    }
  }

func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
    animateCameraToNewGeoFactMarker(mapView: uiViewController.mapView)
  }