SwiftUI:避免使用MKMapView + UIViewRepresentable在TabView中重新创建/渲染视图

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

我有一个带有三个标签的TabView,其中一个包含这样实现的地图视图:

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
        }
    }
}

选项卡视图的实现是这样的:

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)
}

问题是,每次我从其他两个选项卡之一切换回地图选项卡时,都会执行makeUIView(:context)方法。看来,当我切换到另一个选项卡时,基础MKMapView实例已被释放,而当我切换回该选项卡时,将重新创建该实例。在UIKit中,它不会像这样重新渲染整个视图。我是在做错什么,还是有什么办法可以确保在我切换回原样时保留基础的MKMapView实例,这样就不必每次都重新创建它了?

ios mapkit swiftui
2个回答
0
投票

您需要为每个选项卡存储MKMapView的实例并在离开视图之前销毁,因为SwiftUI在需要渲染(例如绑定变量已更改时,它会销毁MapView。)>

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
        }
    }
}

-1
投票

使用EnvironmentObject。始终更新它并在TabView {MapView(coordinates:Object.coordinates)}

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