MKMapView 不保留状态?

问题描述 投票:0回答:1

我有一个非常简单的设置,其中 MapKit 驻留在另一个视图中。我希望地图能够扩展到

fullScreenCover
。地图在初始加载时正确显示在 ProfilePageView 中,并在展开时正确显示在
fullScreenCover
中。然而,当退出
fullScreenCover
时,地图实际上完全消失了(见下图)。再次正确单击矩形会将其返回到正确显示的
fullScreenCover

enter image description here

我可以使用 UUID 密钥强制它重新渲染,但这似乎是一种黑客行为,我不明白为什么有必要。

import Foundation
import SwiftUI
import UIKit
import MapKit

struct ProfilePageView: View {

    @State private var isMapExpanded: Bool = false

    @State private var mapView: MKMapView
    @State private var mapViewKey: UUID = UUID()

    init(countryNames: [String]) {

        // Initialize MKMapView with configuration
        let initialMapView = MKMapView()
        let initialLocation = CLLocationCoordinate2D(latitude: 33.9391, longitude: 67.7100)
        let regionRadius: CLLocationDistance = 6000000
        let coordinateRegion = MKCoordinateRegion(center: initialLocation, latitudinalMeters: regionRadius, longitudinalMeters: regionRadius)
        initialMapView.setRegion(coordinateRegion, animated: true)
        _mapView = State(initialValue: initialMapView)
        print("MKMapView initialized in init")
    }

    var body: some View {
        ScrollView {
                Divider()

                Button(action: {
                    isMapExpanded = true
                }) {
                    ZStack {
                        MapUserView(isMapLoading: .constant(false), mapView: mapView)
                            .id(mapViewKey)  // Use the key to force recreation
                            .frame(height: 425)
                            .cornerRadius(10)
                            .overlay(
                                RoundedRectangle(cornerRadius: 10)
                                    .stroke(Color.blue, lineWidth: 4)
                            )
                            .allowsHitTesting(false)

                        Rectangle()//
                            .foregroundColor(.clear)
                            .frame(height: 425)
                            .contentShape(Rectangle())
                    }
                }
                .buttonStyle(PlainButtonStyle())
                .fullScreenCover(isPresented: $isMapExpanded, onDismiss: {
                    print("FullScreenCover dismissed")
                    mapViewKey = UUID()  // *If this is commented it we get the above described image*
                }) {
                    MapUserFullScreenView(isPresented: $isMapExpanded, mapView: mapView)
                }

            Text("Here we are")

                
            }

        }
    }




struct MapUserFullScreenView: View {
    @Binding var isPresented: Bool
    var mapView: MKMapView
   

    var body: some View {
        ZStack(alignment: .topLeading) {
            MapUserView(isMapLoading: .constant(false), mapView: mapView)
                .edgesIgnoringSafeArea(.all)
            
            Button(action: {
                isPresented = false
            }) {
                Image(systemName: "xmark.circle.fill")
                    .padding()
                    .font(.largeTitle)
                    .foregroundColor(.white)
            }
            .edgesIgnoringSafeArea(.all)
        }
    }
}

struct ProfilePageView_Previews: PreviewProvider {
    static var previews: some View {
        let randomCountries = ["Brazil", "Colombia"]
      
        
        return ProfilePageView(countryNames: randomCountries)
    }
}

import SwiftUI
import MapKit
struct MapUserView: UIViewRepresentable {
    @Binding var isMapLoading: Bool
    
    var mapView: MKMapView

    func makeUIView(context: Context) -> MKMapView {
        print("UI has been made")
        // Ensure the map view is only configured once
        if mapView.delegate == nil {
            mapView.delegate = context.coordinator

        }
        return mapView
    }

    func updateUIView(_ mapView: MKMapView, context: Context) {
        print("updateUIView called")
        // Ensure the map view is not reset or cleared unintentionally
        if mapView.delegate == nil {
            mapView.delegate = context.coordinator
        }
    }

    func makeCoordinator() -> MapUserCoordinator {
        MapUserCoordinator(self)
    }

    class MapUserCoordinator: NSObject, MKMapViewDelegate {
        var parent: MapUserView
        
        private var cancellables = Set<AnyCancellable>()

        var dimmingView: UIView?

        init(_ parent: MapUserView) {
            self.parent = parent
            
            super.init()
        }

        func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
            parent.isMapLoading = false
        }
        
    }
}


struct MapUserView_Previews: PreviewProvider {
    static var previews: some View {

        return MapUserView(isMapLoading: .constant(false), mapView: MKMapView())
    }
}

为什么需要这个 UUID 密钥?为什么

@State
不能正确确保地图视图的状态在
ProfilePageView
内保持共享以及
fullScreenCover
中显示的值的状态?

请注意,我将

mapView
传递给
MapUserView
以启用全屏覆盖显示,而不需要完全重新加载地图信息(我在这里删除了许多复杂的方法以专注于特定问题)。在通过此
mapView
之前,该按钮将导致地图在显示之前完全重新加载,这将导致显着的延迟。

swift swiftui state mapkit render
1个回答
0
投票

makeUIView
需要初始化地图

© www.soinside.com 2019 - 2024. All rights reserved.