What I am trying to accomplish:
- Navigate to MapView defined in ProfileMapView. - This works
- In ProfileMapView, when calloutAccessoryControlTapped method is called Navigate from ProfileMapView when to another view: ProfileDetailsView- This is does not work
//Calling ProfileMapview like this:
@State var pins = [GpsData.MyEndPt]()
ProfileMapView(locationPins: $pins)
// ProfileMapView defined
struct ProfileMapView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@State var tracking:MapUserTrackingMode = .follow
@Environment(\.presentationMode) var presentationMode
@Binding var locationPins: [GpsData.MyEndPt]
var body: some View {
TabView {
NavigationView {
ZStack {
VStack (alignment: .leading){
MapView(locationPins: $locationPins)
.ignoresSafeArea()
}
}
//.edgesIgnoringSafeArea(.all)
.safeAreaInset(edge: .bottom) {
Color.clear
.frame(height: 0)
.background(.white)
}
}
}
struct MapView: UIViewRepresentable {
@Binding var locationPins: [GpsData.MyEndPt]
func makeUIView(context: Context) -> MKMapView {
//...
}
func updateUIView(_ uiView: MKMapView, context: Context) {
//...
}
func makeCoordinator() -> MapViewDelegate{
var del = MapViewDelegate()
del.addEndPoints(endPoints: locationPins)
return del
}
class MapViewDelegate: MKMapView, MKMapViewDelegate {
let PINID:String = "MyEndPoint"
var mylocationPins: [GpsData.MyEndPt] = []
@State var locationId: String?
@State var providerType: String?
public func addEndPoints(endPoints: [GpsData.MyEndPt]) {
self.mylocationPins = endPoints
self.removeAnnotations(endPoints)
self.addAnnotations(endPoints)
self.showAnnotations(endPoints, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
for pin in self.mylocationPins {
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.rightCalloutAccessoryView = UIButton(type: UIButton.ButtonType.detailDisclosure)
subtitleView.text = "Target: "
subtitleView.text! += String(pin.target)
}
mPin!.detailCalloutAccessoryView = subtitleView
return mPin!
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
DispatchQueue.main.async {
if let thumbnailImageButton = view.leftCalloutAccessoryView as? UIButton,
let url = (view.annotation as? GpsData.MyEndPt)?.thumbnailUrl
{
print("URL: \(url)")
do{
let imageData: Data = try Data(contentsOf: url as URL)
let image = UIImage(data: imageData)
thumbnailImageButton.setImage(image, for: UIControl.State.normal)
}catch{
print("Unable to load image data: \(error)")
}
}
}
}
//MARK:- delegate method
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
mapView.deselectAnnotation(view.annotation, animated: true)
for detail in self.mylocationPins {
locationId = detail.locationId
providerType = detail.providerType
NavigationLink(value: control) {
ProfileDetailsView(locationId: $locationId, providerType: $providerType)
}
break
}
}
}
}
}
}
ProfileDetailsView defined like this:
@StateObject var manager = LocationManager()
@State var tracking:MapUserTrackingMode = .follow
@Environment(\.presentationMode) var presentationMode
@Binding var locationId: String?
@Binding var providerType: String?
var body:some View {
VStack (alignment: .leading){
Text("Details here...")
Button {
}
label: {
Text("Share")
.foregroundColor(.blue)
}
.buttonStyle(.bordered)
Button {
}
label: {
Text("Update consumption")
.foregroundColor(.blue)
}
.buttonStyle(.bordered)
}
}
}
I get warning: "Accessing State's value outside of being installed on a View. This will result in a constant Binding of the initial value and will not update." inside ProfileMapView line wheer I define @Binding var locationPins: [GpsData.MyEndPt]. That value is being passed into ProfileMapView - so I dont know why then warning. However, ProfileMapView gets called, the mapview is displayed and the marker pin appears and when I click on the disclosure the navigation to other view ProfileDetailsView does not work. I tried NavigationStack and could not make it work because it threw lot of errors. How to fix the code in calloutAccessoryControlTapped method, so I can navigate to other view: ProfileDetailsView. I have spent a week on this trying various things but it hasn't worked.