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) {
animateCameraToMarker(mapView: uiViewController.mapView)
}