Reputation: 455
I am implementing Google Maps SDK in a SwiftUI project, In this project I bind markers according with a list of order's locations that I request from server.
I am already binding the markers on map, but now I want to centralize the maps with the right zoom on markers, I already did this on the android app version using bounds, and now I want to do the same on swift. But neither mapView.moveCamera()
and mapView.animate()
are working.
I am requesting the camera change in updateUIView(_ mapView: GMSMapView, context: Context)
after that I bind the markers.
The code:
import SwiftUI
import GoogleMaps
import shared
struct GoogleMapsView: UIViewRepresentable {
private let MARKER_SIZE = 40
private let zoom: Float = 15.0
private let bounds: GMSCoordinateBounds = GMSCoordinateBounds()
@Binding var mappedOrders: Dictionary<Int32, [OrderDTO]>
@Binding var filteredOrders: [OrderItem]
@Binding var showAlert: Bool
@Binding var wichAlert: Int
func makeUIView(context: Self.Context) -> GMSMapView {
let camera = GMSCameraPosition.camera(withLatitude: 40.4637, longitude: 3.7492, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ mapView: GMSMapView, context: Context) {
mapView.clear()
for (key) in mappedOrders.keys {
let orderList: [OrderDTO] = mappedOrders[key]!
orderList.filter { order in
return order.deliveryStateString == "rider_assigned" ||
order.deliveryStateString == "delivery_in_progress" ||
order.deliveryStateString == "pending_rider"
}.forEach{ order in
switch order.deliveryState {
case .deliveryInProgress:
if (order.deliveryLocation != nil) {
createDeliveryPointMarker(order: order).map = mapView
}
break
case .pendingRider:
if (order.deliveryLocation != nil) {
createDeliveryPointMarker(order: order).map = mapView
}
if(order.restaurantLocation != nil) {
createRestaurantMarker(order: order).map = mapView
}
break
case .riderAssigned:
if (order.deliveryLocation != nil) {
createDeliveryPointMarker(order: order).map = mapView
}
if(order.restaurantLocation != nil) {
createRestaurantMarker(order: order).map = mapView
}
break
default:
break
}
}
}
let update = GMSCameraUpdate.fit(bounds)
mapView.animate(with: update)
}
private func createDeliveryPointMarker(order: OrderDTO) -> GMSMarker {
let location = CLLocationCoordinate2DMake(
order.restaurantLocation!.latitude,
order.restaurantLocation!.longitude
)
let marker = GMSMarker(
position: location
)
bounds.includingCoordinate(location)
marker.title = order.user
marker.userData = MarkerDataStored(
order: order,
isClientMarker: true
)
let iconName:String
switch order.deliveryState {
case .pendingRider:
iconName = "flag_red"
break
case .riderAssigned:
iconName = "flag_blue"
break
default:
iconName = "flag_green"
break
}
marker.isTappable = true
marker.icon = resizeImage(
image: UIImage(named: iconName)!,
scaledToSize: CGSize(width: MARKER_SIZE, height: MARKER_SIZE)
)
return marker
}
private func createRestaurantMarker(order: OrderDTO) -> GMSMarker {
let marker = GMSMarker(
position: CLLocationCoordinate2DMake(
order.deliveryLocation!.latitude,
order.deliveryLocation!.longitude
)
)
marker.title = order.user
marker.userData = MarkerDataStored(
order: order,
isClientMarker: false
)
let iconName:String
switch order.deliveryState {
case .pendingRider:
iconName = "restaurant_red"
break
default:
iconName = "restaurant_blue"
break
}
marker.isTappable = true
marker.icon = resizeImage(
image: UIImage(named: iconName)!,
scaledToSize: CGSize(width: MARKER_SIZE, height: MARKER_SIZE)
)
return marker
}
func makeCoordinator() -> MapsDelegate {
let delegate = MapsDelegate()
delegate.onClickMarker = { marker in
filterByRestaurant(marker: marker)
wichAlert = OPEN_RESTAURANT_ORDERS
showAlert = true
}
return delegate
}
private func filterByRestaurant(marker: GMSMarker) {
let data: MarkerDataStored = marker.userData as! MarkerDataStored
filteredOrders.removeAll()
if (data.isClientMarker) {
filteredOrders.append(OrderItem(order: data.order))
} else {
self.mappedOrders[data.order.commercialPremiseId]?.forEach() { order in
filteredOrders.append(OrderItem(order: order))
}
}
}
}
struct MarkerDataStored {
let order: OrderDTO
let isClientMarker: Bool
}
Upvotes: 1
Views: 1964
Reputation: 19044
The correct way is :
Change this line
bounds.includingCoordinate(location)
with this
bounds = bounds.includingCoordinate(location)
Upvotes: 1