我有一个非常简单的设置,其中 MapKit 驻留在另一个视图中。我希望地图能够扩展到
fullScreenCover
。地图在初始加载时正确显示在 ProfilePageView 中,并在展开时正确显示在 fullScreenCover
中。然而,当退出 fullScreenCover
时,地图实际上完全消失了(见下图)。再次正确单击矩形会将其返回到正确显示的 fullScreenCover
。
我可以使用 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
之前,该按钮将导致地图在显示之前完全重新加载,这将导致显着的延迟。
makeUIView
需要初始化地图