Post

Replies

Boosts

Views

Activity

Reply to MKMapview overlay renderding performance issue on iOS16
struct UIMapView: UIViewRepresentable { typealias UIViewType = MKMapView // MARK: Properties @ObservedObject var mapViewModel: MapViewModel @State private(set) var mapViewEvents: PassthroughSubject<MapViewActionType, Never>? = PassthroughSubject() @State private(set) var magnifierEvents: PassthroughSubject<MagnifierHotPoint, Never>? = PassthroughSubject() private(set) var mapView = MKMapView() private let kAutoSnapDelta = 1.0 // MARK: - UIViewRepresentable func makeCoordinator() -> UIMapCoordinator { return UIMapCoordinator(for: self) } func makeUIView(context: Context) -> UIViewType { configureMapView(context: context) DispatchQueue.main.async { setupSubscribers(context: context) context.coordinator.setupUserDefaultsObserver() } return mapView } func updateUIView(_ mapView: MKMapView, context: Context) { configureMapView(context: context, renderingMapView: mapView) handleMapLayerRendering(context: context, on: mapView) } // MARK: - Private Methods private func configureMapView(context: Context, renderingMapView: MKMapView? = nil) { let mapView = renderingMapView ?? mapView mapView.delegate = context.coordinator mapView.userTrackingMode = .none mapView.showsCompass = true if mapView.mapType != mapViewModel.mapType.mkType { mapView.mapType = mapViewModel.mapType.mkType } mapView.tag = 10001 // tag to identity view let cameraZoomRange = MKMapView.CameraZoomRange(minCenterCoordinateDistance: 5, maxCenterCoordinateDistance: 2000) mapView.setCameraZoomRange(cameraZoomRange, animated: false) } private func setupSubscribers(context: Context) { context.coordinator.setupSubscribers( mapViewEvents: mapViewEvents, magnifierEvents: magnifierEvents ) } private func handleMapLayerRendering(context: Context, on mapView: MKMapView) { switch mapViewModel.mapLayerRendering { case .none: break case .all: renderGeometries(mapView: mapView) zoomToActiveFence(mapView: mapView, viewMode: mapViewModel.mapViewMode) addSitePinAnnotation(siteModel: mapViewModel.parentSite) mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .refreshLayers: reRenderAllGeometries(mapView: mapView) // No need to set 'mapLayerRendering' to none, as it is done in reRenderAllGeometries case .renderLayer(let layerId): if let layer = mapViewModel.layers.first(where: { $0.layerId == layerId }), !layer.hidden { renderGeometriesForLayer(layerId: layerId, mapView: mapView) zoomToActiveFence(mapView: mapView, viewMode: mapViewModel.mapViewMode) } mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .renderForDeletedLayer(let layerId): removeGeometry(with: layerId, mapView: mapView) mapViewModel.setMapLayerRenderingMode(to: .none) case .toggleLayer(let layerId, let hidden): if hidden { removeGeometry(with: layerId, mapView: mapView) } else { renderGeometriesForLayer(layerId: layerId, mapView: mapView) } mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .vertexDrawing(let layerId, let hidden): if hidden { lockLayer(with: layerId, mapView: mapView) } else { unlockLayer(with: layerId, mapView: mapView) renderGeometriesForLayer(layerId: layerId, mapView: mapView) } mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .selectAnnotation(let gateModel): setGateSelection(mapView: mapView, gateModel: gateModel) mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) } // MARK: - Configuring view state private func configureMapView(_ mapView: UIViewType, context: UIViewRepresentableContext<UIMapView>) { if mapView.mapType != mapViewModel.mapType.mkType { mapView.mapType = mapViewModel.mapType.mkType // Since the map type has been changed, change magnifier preview context.coordinator.startMagnifierFromCurrentContext() } mapView.showsUserLocation = mapViewModel.showsUserlocation // Update Magnifier POI(hot point) if it is active. // It will updated on active layer change as well context.coordinator.updateMagnifierPOI() }
Jul ’24
Reply to MKMapview overlay renderding performance issue on iOS16
Hi, I have made changes but I am not sure how 2 overlay rendering lags. I can understand when we have array of overlays. I am attaching video link here which depict the behaviour. It has only TWO overlays (FenceSegmentPolyline: MKPolyline) and performance is lagging. Let me know if it help. I am also sharing UIViewRepresentable Mapview. DropBox Link : https://www.dropbox.com/scl/fi/o91nz6gd8gts4f5v0fiqk/Overlay_behaviour_recording.mov?rlkey=bb9oq4i01meli17onhwonk83i&dl=0 struct UIMapView: UIViewRepresentable { typealias UIViewType = MKMapView // MARK: Properties @ObservedObject var mapViewModel: MapViewModel @State private(set) var mapViewEvents: PassthroughSubject<MapViewActionType, Never>? = PassthroughSubject() @State private(set) var magnifierEvents: PassthroughSubject<MagnifierHotPoint, Never>? = PassthroughSubject() private(set) var mapView = MKMapView() private let kAutoSnapDelta = 1.0 // MARK: - UIViewRepresentable func makeCoordinator() -> UIMapCoordinator { return UIMapCoordinator(for: self) } func makeUIView(context: Context) -> UIViewType { configureMapView(context: context) DispatchQueue.main.async { setupSubscribers(context: context) context.coordinator.setupUserDefaultsObserver() } return mapView } func updateUIView(_ mapView: MKMapView, context: Context) { configureMapView(context: context, renderingMapView: mapView) handleMapLayerRendering(context: context, on: mapView) } // MARK: - Private Methods private func configureMapView(context: Context, renderingMapView: MKMapView? = nil) { let mapView = renderingMapView ?? mapView mapView.delegate = context.coordinator mapView.userTrackingMode = .none mapView.showsCompass = true if mapView.mapType != mapViewModel.mapType.mkType { mapView.mapType = mapViewModel.mapType.mkType } mapView.tag = 10001 // tag to identity view let cameraZoomRange = MKMapView.CameraZoomRange(minCenterCoordinateDistance: 5, maxCenterCoordinateDistance: 2000) mapView.setCameraZoomRange(cameraZoomRange, animated: false) } private func setupSubscribers(context: Context) { context.coordinator.setupSubscribers( mapViewEvents: mapViewEvents, magnifierEvents: magnifierEvents ) } private func handleMapLayerRendering(context: Context, on mapView: MKMapView) { switch mapViewModel.mapLayerRendering { case .none: break case .all: renderGeometries(mapView: mapView) zoomToActiveFence(mapView: mapView, viewMode: mapViewModel.mapViewMode) addSitePinAnnotation(siteModel: mapViewModel.parentSite) mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .refreshLayers: reRenderAllGeometries(mapView: mapView) // No need to set 'mapLayerRendering' to none, as it is done in reRenderAllGeometries case .renderLayer(let layerId): if let layer = mapViewModel.layers.first(where: { $0.layerId == layerId }), !layer.hidden { renderGeometriesForLayer(layerId: layerId, mapView: mapView) zoomToActiveFence(mapView: mapView, viewMode: mapViewModel.mapViewMode) } mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .renderForDeletedLayer(let layerId): removeGeometry(with: layerId, mapView: mapView) mapViewModel.setMapLayerRenderingMode(to: .none) case .toggleLayer(let layerId, let hidden): if hidden { removeGeometry(with: layerId, mapView: mapView) } else { renderGeometriesForLayer(layerId: layerId, mapView: mapView) } mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .vertexDrawing(let layerId, let hidden): if hidden { lockLayer(with: layerId, mapView: mapView) } else { unlockLayer(with: layerId, mapView: mapView) renderGeometriesForLayer(layerId: layerId, mapView: mapView) } mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) case .selectAnnotation(let gateModel): setGateSelection(mapView: mapView, gateModel: gateModel) mapViewModel.setMapLayerRenderingModeonAsyncThread(to: .none) } // MARK: - Configuring view state private func configureMapView(_ mapView: UIViewType, context: UIViewRepresentableContext<UIMapView>) { if mapView.mapType != mapViewModel.mapType.mkType { mapView.mapType = mapViewModel.mapType.mkType // Since the map type has been changed, change magnifier preview context.coordinator.startMagnifierFromCurrentContext() } mapView.showsUserLocation = mapViewModel.showsUserlocation // Update Magnifier POI(hot point) if it is active. // It will updated on active layer change as well context.coordinator.updateMagnifierPOI() }
Jul ’24