简体   繁体   中英

Google Maps iOS SDK animate map padding SwiftUI

I'm looking to animate my Google Map's padding, as when a bottom sheet appears, the map padding resizes dynamically.

The GMSMapView.padding documentation says it can be accomplished with a UIView block based animation, but I'm not sure how that would tie in to a SwiftUI application?

The bottom sheet works fine, it shows when expected and passes the correct padding value through to the MapView. It's just the animation I can't figure out. (The bottom sheet uses this component if you're curious https://github.com/LucasMucGH/BottomSheet )

Any help would be greatly appreciated, thanks.

Current relevant code:

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
  }

If anyone's interested I worked out how to do it. The solution was simpler than I expected, it's literally just wrapping the padding parameter in a UIView.animate closure, then calling it in the updateUIViewController method:

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)
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM