-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Annotations don't update on map if they are updated in ContentView.swift #3
Comments
Just stumbled into this same exact issue. |
Hi, I'm having the same issue! @anark @zacharyblank, Have you managed to make it work? my updateAnnotations function looks like this:
this part actually adds a marker on the map: When I follow the guide works perfectly for me but my annotations are fetched via a network request and passed down to the mapview via a @published variable. |
I also ran into this issue not just with annotations but with any of the @published or bindable data passed into the mapView. Ex: mapView.styleURL or mapView.UserTrackingMode. The map just never updates to reflect the changes dynamically. |
Looks like the team is not active at all. |
Hi. Thank you for looking at this demo. This repository is not a Mapbox framework; is the companion code for this tutorial: https://docs.mapbox.com/help/tutorials/ios-swiftui/ Mapbox is an UIKit based framework with a cocoa MVC architecture that relies on a view controller implementation to control the lifecycle of all the controller's views. This repository explains how the Mapbox Maps SDK for iOS can be integrated with the newly developed Apple's SwiftUI technology. SwiftUI takes a react native architectural approach (or smalltalk like if you are familiar) to propagate changes. In the
And in the
Which tells SwiftUI to observe any changes in This repo is for reporting issues on the tutorial. For support or assistance with "how to" questions, please reach out to our support team. You can also ask other users on StackOverflow. |
@fabian-guerra I have reached out to your support team countless times without replies. Using the code above just like in the tutorial does not work. Same goes for other parameters as well. The map never updates after its rendered the initial time. The only version that does work is the pure UIKit code without SwiftUI in the mix. |
Hi, @CodyPChristian. In my comment #3 (comment) I explained why is not working. SwiftUI has a different approach to update ui elements. The code in this comment #3 (comment) intends to follow the UIKit pattern. That is why is not a Mapbox nor this tutorial issue but how you use SwiftUI. From Apple's documentation
|
Hi @fabian-guerra |
Hi @folivi. Just to clarify:
I wrote the tutorial and this companion code. What you are saying is that I don't know about the code I wrote?
What you are saying is that since you are a paid customer we are not providing a prompt technical support? Reading again my comment #3 (comment) I realized that I was not clear enough to state that to apply any changes to the view, you have to update For reference on learning how to control the view's appearance based on data changes I suggest you read Apple's documentation: https://developer.apple.com/documentation/swiftui/state_and_data_flow I am waiting for your reply with the answers for the above questions. |
Hi @fabian-guerra
I mean by this that we are here commenting a tutorial when maybe we should be reaching out to someone from the Mapbox development team to report the issue. I contacted the Mapbox twitter, no response, created a ticket, still no reaction. This has nothing to do with your tutorial. |
Hi, @folivi. Thank you for clarifying. I am a team member of the Mapbox Maps SDK for iOS too.
Yes, as I mentioned in my previous comments you have to update the In this example I am adding and removing an annotation updating
|
Thank again for your time.
In the Mapview
After 3 seconds you will see the log in the console print 3 but the annotations won't change. |
Thanks for the replies @fabian-guerra. Just like @folivi I’m still unable to get your sample above to work as you stated. Here is a gist of my code when I filed the original support ticket. In this case I was trying to change the map style and toggle user location tracking using SwiftUI. The annotations in this example are not bindable on purpose as I don’t change them after the map loads, however i have another version of this that does have them dynamic similar to @folivi https://gist.github.com/CodyPChristian/3bfa0faa85bbc686278e7bffc57f5790 |
Hi. I have modified my example and works too:
Thank you all for using Mapbox. The above proves that this has nothing to do with our SDK but with SwiftUI. I will keep this ticket closed. |
@fabian-guerra thanks I appreciate your help. I will give this latest code a test tonight. Can you confirm if the styleURL can be updated from SwiftUI in a similar approach? |
@fabian-guerra I have spent some time tonight messing with your latest examples and I can not get them working. I can see in the console that the updateUIView does fire when I hit the button or when the timer fires, but there is no new annotations on the map. One difference though is you are using MGLPointAnnotation where I am using CustomPointAnnotation from one of the other Mapbox tutorials. Outside of that our setup is the same. |
@fabian-guerra okay I did some more testing. I took this repo and applied your demo above and upgraded it to 5.6.0 and it worked great. However the second I tried to duplicate your logic and set mapView.styleURL in a similar way to what you did with Annotations, the map view stopped updating for both the Annotations and the mapStyle. Next I removed that code back to where annotations work and replaced the annotations with the CustomPointAnnotations found in https://docs.mapbox.com/ios/maps/examples/custom-callout/ which show up fine, until you try to update them like you are doing in your demo, once again the map doesnt update the annotations. Can you please explain why this is the case? What key thing are we missing that is causing plain MGLAnnotations to work but once you extend them like CustomPointAnnotation or other properties on mapView like mapView.styleURL cause the map to suddenly no longer update? One thing that does sorta work is instead of doing self.styleURL inside of a button I did it inside the DispatchQueue you added in your last example above and that time it did update the map style but at the same time it broke the annotations that was working before that timer fired. Something funky is going on for sure. Thanks |
@CodyPChristian have you figure out how to solve your issue? |
@folivi Not yet, did you? Hoping @fabian-guerra can take a look at my previous message and help out. Thanks |
@folivi @fabian-guerra I made a discovery today as well. I managed to get the one issue working where I couldn't update the map style (mapView.styleURL), I called it within a DispatchQueue.main from a Button instead of an ActionSheet and it works fine. Now I wonder why the ActionSheet doesn't work. Very interesting. Here is what I changed. From: Button(action: {
self.showingSheet = true
}){
Text("Map Style")
}.actionSheet(isPresented: $showingSheet) {
ActionSheet(title: Text("Map Settings"), message: Text("Select Map Style"), buttons: [
.default(Text("Dark")) {
DispatchQueue.main.async() {
self.styleURL = URL(string: "mapbox://styles/REDACTED")!
}
},
.default(Text("Satellite")) {
DispatchQueue.main.async() {
self.styleURL = URL(string: "mapbox://styles/REDACTED")!
}
},
.default(Text("Default Streets")) {
DispatchQueue.main.async() {
self.styleURL = URL(string: "mapbox://styles/mapbox/streets-v11")!
}
},
.cancel()
])
} To: Button(action: {
DispatchQueue.main.async() {
self.styleURL = URL(string: "mapbox://styles/mapbox/streets-v11")!
}
}){
Text("Streets")
}
Button(action: {
DispatchQueue.main.async() {
self.styleURL = URL(string: "mapbox://styles/REDACTEDr")!
}
}){
Text("Dark")
}
Button(action: {
DispatchQueue.main.async() {
self.styleURL = URL(string: "mapbox://styles/REDACTED")!
}
}){
Text("Satellite")
} I also tested the user location stuff again using a Button like above and that also works. I pass the @State variables into MapView like so: MapView(annotations: $annotations, styleURL: $styleURL, trackUser: $trackUser) and within MapView.swift I did the following to get everything working. struct MapView: UIViewRepresentable {
@Binding var annotations: [MGLPointAnnotation]
@Binding var styleURL: URL
@Binding var trackUser: Bool
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MGLMapView {
mapView.delegate = context.coordinator
mapView.styleURL = self.styleURL
trackingUser()
return mapView
} func updateUIView(_ uiView: MGLMapView, context: UIViewRepresentableContext<MapView>) {
updateAnnotations()
mapView.styleURL = self.styleURL
trackingUser()
} private func trackingUser(){
if self.trackUser {
mapView.showsUserLocation = true
mapView.userTrackingMode = .followWithHeading
} else {
mapView.showsUserLocation = false
mapView.userTrackingMode = .none
}
} |
@CodyPChristian |
@CodyPChristian @folivi I was facing the same issue. When I bind something on content view, the map view stop refreshing. Then I use mapview that was created on makeUIView just on coordinator, to get delegate functions, to update annotations, user location, style I'm using uiView from updateUIView and everything is working fine. |
I can confirm that to some extent example provided by @fabian-guerra works. However, I found no way to populate the map with externally provided data (e.g after making a request to the API). Making an async call first seem to block all the consequent of altering of bound data on the map. |
Hi @fabian-guerra! Can you please clarify something: The demo stops showing any new added annotation when a Text() is added above the MapView() call like bellow:
Does this have to do with the SwiftUI propagation and new UI update pattern? Or am I doing something wrong? Thanks for any insights (or for pointing out what I am doing wrong). Best regards,
|
I was having the same issue. The following worked for me:
You have to use the |
Thanks! This does make it work! |
You saved my day! |
Thank you very much! You've just saved my final year project! |
If I append an annotation to the annotation variable in ContentView.swift I expect it to show up on the map in the mapView.
Using a debugger I can see that the annotation variable is in fact updated in the mapView and updateUiView is called, however the marker never appears on the map. What needs to be done to make these changes appear on the mapView?
The text was updated successfully, but these errors were encountered: