I have integrated Mapbox with SwiftUI using the following example:
https://github.com/mapbox/mapbox-maps-swiftui-demo
It works fine. However when trying to display other @State variables on the View Stack, the UI Refresh propagation stops going down to the Mapbox call updateUIView()
For example, you can replicate the problem by replacing ContentView.swift from the above repository with the following code:
import SwiftUI
import Mapbox
struct ContentView: View {
@State var annotations: [MGLPointAnnotation] = [
MGLPointAnnotation(title: "Mapbox", coordinate: .init(latitude: 37.791434, longitude: -122.396267))
]
var body: some View {
ZStack {
VStack {
MapView(annotations: $annotations).centerCoordinate(.init(latitude: 37.791293, longitude: -122.396324)).zoomLevel(16)
Button(action: {
let rand = Float.random(in: 37.79...37.80)
self.annotations.append(MGLPointAnnotation(title: "Mapbox", coordinate: .init(latitude: CLLocationDegrees(rand), longitude: -122.396261)))
}) {
Text("Button")
Text("\(self.annotations.count)")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Running the above code indicates that the Text("\(self.annotations.count)")
UI gets updated - however, the annotations are not refreshed (hence updateUIView()
is not called).
If I comment // Text("\(self.annotations.count)")
then annotations are refreshed (and updateUIView()
is called)
Does anybody have any ideas of what might be the issue? Or am I missing something here?
Thanks!
Answering my own question here thanks to this post
https://github.com/mapbox/mapbox-maps-swiftui-demo/issues/3#issuecomment-623905509
In order for this to work it is necessary to update the UIView being rendered inside Mapview:
func updateUIView(_ uiView: MGLMapView, context: Context) {
updateAnnotations(uiView)
trackUser()
}
private func updateAnnotations(_ view: MGLMapView) {
if let currentAnnotations = view.annotations {
view.removeAnnotations(currentAnnotations)
}
view.addAnnotations(annotations)
}