我有一个包含三个选项卡的 TabView,其中一个包含这样实现的 map View :
struct MapView: UIViewRepresentable {
let region: MKCoordinateRegion
let animatedRegion: Bool
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
mapView.showsUserLocation = true
mapView.setRegion(region, animated: animatedRegion)
return mapView
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func updateUIView(_ mapView: MKMapView, context: Context) {
}
class Coordinator: NSObject, MKMapViewDelegate {
var control: MapView
init(_ control: MapView) {
self.control = control
}
}
}
标签 View 是这样实现的:
TabView(selection: $selection) {
MapView(/* params */)
.tabItem {
Image(systemName: "1.square.fill")
Text("map")
}.tag(1)
Text("Screen #2")
.tabItem {
Image(systemName: "2.square.fill")
Text("2")
}.tag(2)
Text("Screen #3")
.tabItem {
Image(systemName: "3.square.fill")
Text("3")
}.tag(3)
}
问题是每次我从其他两个选项卡之一切换回 map 选项卡时都会执行 makeUIView(:context) 方法。当我切换到另一个选项卡时,底层 MKMapView 实例似乎被释放,然后当我切换回来时它被重新创建。在 UIKit 中,它不会像那样重新渲染整个 View 。我是不是做错了什么,或者我能做些什么来确保在我切换回来时保留底层 MKMapView 实例,这样它就不必每次都重新创建它?
最佳答案
您需要为每个选项卡存储 MKMapView
实例并在离开 View 之前销毁,因为 SwiftUI 会在需要渲染时销毁 MapView,例如绑定(bind)变量已更改。
struct MapView: UIViewRepresentable {
@Binding var currentTab: Int
static private var mapViews = [Int: MKMapView]()
let region: MKCoordinateRegion
let animatedRegion: Bool
func makeUIView(context: Context) -> MKMapView {
guard MapView.mapViews[currentTab] != nil else { return MapView.mapViews[currentTab]! }
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
mapView.showsUserLocation = true
mapView.setRegion(region, animated: animatedRegion)
MapView.mapViews[currentTab] = mapView
return mapView
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func updateUIView(_ mapView: MKMapView, context: Context) {
}
class Coordinator: NSObject, MKMapViewDelegate {
var control: MapView
init(_ control: MapView) {
self.control = control
}
}
}
关于ios - SwiftUI:避免使用 MKMapView+UIViewRepresentable 在 TabView 中重新创建/重新渲染 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58093295/