SwiftUI: избегайте воссоздания / повторного отображения представления в TabView с помощью MKMapView + UIViewRepresentable - PullRequest
1 голос
/ 25 сентября 2019

У меня есть 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 сохраняется, когда я переключаюсь назад, чтобы ему не приходилось воссоздавать его каждый раз?

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Вам необходимо сохранить экземпляр 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
        }
    }
}
0 голосов
/ 25 сентября 2019

использовать EnvironmentObject.всегда обновляйте его и передавайте в TabView {MapView (координаты: Object.coordinates)}

...