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()
}
Post
Replies
Boosts
Views
Activity
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()
}
Attaching Timer Profiler Screenshot.