Open IraklisElef opened 1 year ago
You are right - this is one of the issues that #38 is trying to fix - could you please try whether your gesture works when targeting that branch?
Got the same problem. Using the Branch https://github.com/iakov-kaiumov/Map didn't solve the problem for me.
Hope this get fixed soon as the library is amazing and I would love to use it!
@JohannesWi Hi! Could you provide an example of code that is not working for you, please? It will help me to solve the issue. In my project everything works fine.
Thanks for your response @iakov-kaiumov ! Im using the same example as @IraklisElef is doing. My code looks like this:
Map(
coordinateRegion: $region,
type: .standard,
pointOfInterestFilter: .excludingAll,
informationVisibility: .default.union(.userLocation),
interactionModes: [.all],
annotationItems: markers,
annotationContent: { location in
ViewMapAnnotation(coordinate: location.coordinate) {
Color.red
.frame(width: 24, height: 24)
.clipShape(Circle())
.onTapGesture {
print("test")
}
}
}
)
.frame(height: 350)
.cornerRadius(8)
@JohannesWi This is really strange, because this code works for me. Attaching screen recording and code fragment.
struct Annotation: Identifiable {
let id = UUID()
let coordinate: CLLocationCoordinate2D
let clusteringIdentifier: String
}
struct ContentView: View {
@State private var region = MKCoordinateRegion(
center: .init(latitude: 50, longitude: 10),
latitudinalMeters: 100_000,
longitudinalMeters: 100_000
)
@State private var annotations = [
Annotation(coordinate: .init(latitude: 49.5, longitude: 09.5), clusteringIdentifier: "a"),
Annotation(coordinate: .init(latitude: 49.5, longitude: 10.0), clusteringIdentifier: "a"),
Annotation(coordinate: .init(latitude: 49.5, longitude: 10.5), clusteringIdentifier: "a"),
Annotation(coordinate: .init(latitude: 50.0, longitude: 09.5), clusteringIdentifier: "b"),
Annotation(coordinate: .init(latitude: 50.0, longitude: 10.0), clusteringIdentifier: "b"),
Annotation(coordinate: .init(latitude: 50.0, longitude: 10.5), clusteringIdentifier: "b"),
Annotation(coordinate: .init(latitude: 50.5, longitude: 09.5), clusteringIdentifier: "b"),
Annotation(coordinate: .init(latitude: 50.5, longitude: 10.0), clusteringIdentifier: "b"),
Annotation(coordinate: .init(latitude: 50.5, longitude: 10.5), clusteringIdentifier: "b"),
]
@State private var isPresented: Bool = false
var body: some View {
Map(
coordinateRegion: $region,
type: .standard,
pointOfInterestFilter: .excludingAll,
informationVisibility: .default.union(.userLocation),
interactionModes: [.all],
annotationItems: annotations,
annotationContent: { location in
ViewMapAnnotation(coordinate: location.coordinate) {
Color.red
.frame(width: 24, height: 24)
.clipShape(Circle())
.onTapGesture {
isPresented.toggle()
}
}
}
)
.cornerRadius(8)
.alert(isPresented: $isPresented) { Alert(title: Text("Tapped!")) }
}
}
The branch of @iakov-kaiumov did it for me! It also fixed the weird bug with the annotation where it misplaces itself when applying the .ignoresSafeArea() modifier. However, there is another weird bug. When I press the annotation, instead of showing one sheet, it kind of shows 2 sheets one on top of the other, here is a screen recording:
@iakov-kaiumov thank you very much for your reply! I have my map view inside a ZStack and added a custom color above which didn't work with the touch-event.
It would be great if this branch could be merged soon
The branch of @iakov-kaiumov did it for me! It also fixed the weird bug with the annotation where it misplaces itself when applying the .ignoresSafeArea() modifier. However, there is another weird bug. When I press the annotation, instead of showing one sheet, it kind of shows 2 sheets one on top of the other, here is a screen recording:
Could you please tell a little bit more about how you present the sheet? Such behaviour cannot occur when using one .sheet
modifier even if the touch event trigger twice. Moreover, in my case, touch event fires only once, so, I guess that the problem is connected with your sheets implementation.
Ok so, I have an array of annotations. Each annotation has coordinates and some other data. Whenever I am presenting this annotation, I want to be able to click it and then show a sheet. This sheet needs the annotation's data. However, I noticed that the sheet does not take the correct annotation. It takes data from another annotation. Moreover, if I use instead a NavigationLink instead of a sheet, it shows the correct data every time. Do you have any clue of what is going on?
I figured it out. Here is my code:
`Map(
coordinateRegion: $region,
type: .standard,
pointOfInterestFilter: .includingAll,
interactionModes: [.all],
annotationItems: mapInformation.evChargers,
annotationContent: { charger in
ViewMapAnnotation(coordinate: (charger.addressInfo?.coordinates)!) {
Image(K.Images.SupplementarilyIcons.pinpoint)
.resizable()
.frame(width: 40, height: 40, alignment: .center)
.onTapGesture {
showingSheet.toggle()
}
.sheet(isPresented: $showingSheet) {
EVChargerView(evCharger: charger)
} //: SHEET
} //: VIEW MAP ANNOTATION
} //: ANNOTATION CONTENT
) //: MAP`
As you can see, whenever the user taps the image. the showingSheet variable toggles to true, which ends up activating the sheet. Inside that sheet I have a view which takes as a parameter the annotation. However, because, as I understand, the Map struct keeps updating, it keeps passing every time a new annotation to the sheet view, which ends up creating not two sheets, but as many as there are annotations. Now that I know the issue, I am not sure how to work around it so that it passes only one annotation. I tried saving to a separate variable the annotation that the user taps on, and then passing that variable to the sheet view, but for some reason it does not save it. Any ideas?
@IraklisElef As I thought, the problem is not connected with the Map library. To show the sheet correctly, try the following code:
struct YourView: View {
...
@State private var selectedAnnotation: Annotation? = nil
var body: some View {
Map(
coordinateRegion: $region,
annotationItems: annotations,
annotationContent: { annotation in
ViewMapAnnotation(coordinate: annotation.coordinate) {
Image(K.Images.SupplementarilyIcons.pinpoint)
.resizable()
.frame(width: 40, height: 40, alignment: .center)
.onTapGesture {
selectedAnnotation = annotation
}
}
}
)
.sheet(item: $selectedAnnotation) { annotation in
List {
Text("Sheet! \(annotation.id.uuidString)")
}
}
}
}
Game changing solution! Thank you! Could I ask you one more question? I am trying to use the clusterAnnotation property of the Map struct. However, I am not really sure how to implement it. Any suggestions?
You may take a look at the examples in the readme. Also, if you are using my branch, update it to the latest version, please.
I have taken a look. However, I have not seen any mentions on how to use the clusterAnnotation property, nor have I seen any examples of it.
For the clusterAnnotation, first make sure to set the clusteringIdentifier
parameter when initializing the ViewMapAnnotation
. Annotations with the same clusteringIdentifier will be clustered, so make sure to not make that identifier fully unique, but according to some categorization or use the same for all annotations in use (depending on how you would like to cluster them), then the clusterAnnotation
parameter in the Map-initializer will be called whenever the MKMapView decides to create clusters.
I want the clustering to work whenever the user zooms out too much and the annotations are on top of each other. Does that mean that I will need to have the same clusteringIdentifier
for all my annotations? Also, when I am trying to use clusterAnnotation
, it asks me for 2 parameters. One is MKClusterAnnotation
and the other the annotation items that I passed earlier on the annotationItems
parameter. Could you give me an example of what to pass on MKClusterAnnotation
? One last thing. I see that you've included an anchor
parameter in the ViewMapAnnotation
. What values would I need to pass on my CGPoint to anchor my annotation (basically in the middle bottom part of my image) on this spot:
clusteringIdentifier
for all annotations. I've managed to integrate a clusterAnnotation
. One last question if you know the answer. Is it possible to cluster more annotations? What I am trying to say is, let's say that the user is currently zoomed out 25% and the number of annotations that are clustered is 20. I want to be able to cluster, for example 30 annotations, if the user is zoomed out by the same 25%. So basically make the area that is needed to cluster smaller. Is that possible or Swift has a default value for it?
I'm not sure whether this is even possible in MKMapView. @IraklisElef do you have a working example on how this would be implemented using MKMapView? If it is not possible there, it will not be possible here, since this is just a wrapper around the UIKit view.
No I do not have a working example using MKMapView. I reckoned it would not be possible; nevertheless, I asked you in case you knew something I did not know. One question @pauljohanneskraft. On the example you provided on clustering annotations, here, I see that you've include one line of code that I do not understand its purpose, this one: let _ = assert(Set(members.map(\.clusteringIdentifier)).count == 1)
. Could you explain what it does? I removed this line of code and the clustering still worked.
You can remove it.
It has been part of the example to show that only annotations with the same clusteringIdentifier exist in a cluster (i.e. that the set of clusteringIdentifiers has a count of 1) and asserts this to be true (i.e. it would fail, if that weren't the case).
I've managed to integrate a
clusterAnnotation
. One last question if you know the answer. Is it possible to cluster more annotations? What I am trying to say is, let's say that the user is currently zoomed out 25% and the number of annotations that are clustered is 20. I want to be able to cluster, for example 30 annotations, if the user is zoomed out by the same 25%. So basically make the area that is needed to cluster smaller. Is that possible or Swift has a default value for it?
If I understand you correctly, your problem is that your annotations are not collapsing even if they visually intersect. This is an unsolved issue of my implementation (MKViewAnnotation frame is smaller than it should be). To solve the issue, try this branch #40
I've tested it and it works as expected. I hope soon it will be merged.
Is it safe to use or are there any bugs?
The onTapGesture is not working inside the ViewMapAnnotation, here is my code: