Jhonata Ávila
Jhonata Ávila

Reputation: 455

How can i update google maps camera position on IOS SwiftUI

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

Answers (1)

Raja Kishan
Raja Kishan

Reputation: 19044

The correct way is :

Change this line

bounds.includingCoordinate(location)

with this

bounds = bounds.includingCoordinate(location)

Upvotes: 1

Related Questions