UIKit обновление SwiftUI @State вызывает «Изменение состояния во время обновления представления» - PullRequest
1 голос
/ 28 февраля 2020

У меня есть компонент SwiftUI, загружающий MapKit следующим образом:

struct AddressView: View {

    @State private var showingPlaceDetails = false

    var body: some View {
        MapView(showPlaceDetails: self.$showPlaceDetails)
    }
}

Компонент MapView представляет собой структуру MapKit, использующую технику обертывания UIKit -> SwiftUI:

struct MapView: UIViewRepresentable {

    @Binding var showingPlaceDetails: Bool

    func makeUIView(context: Context) -> MKMapView {

        let map = MKMapView()

        map.delegate = context.coordinator

        return map
    }

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

    final class Coordinator: NSObject, MKMapViewDelegate {

        var control: MapView

        init(_ control: MapView) {
            self.control = control
        }

        func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {

              // This is where the warning happen
              self.control.showingPlaceDetails = true
        }
    }
}

Так что мутирует showPlaceDetails выводит это предупреждение: [SwiftUI] Modifying state during view update, this will cause undefined behavior.

Как мне очистить этот код? Является ли эта реализация правильной?

Я понимаю, что я изменяю через @Binding родительское свойство @State, которое будет перерисовывать AddressView с MapView.

Я понимаю, почему это плохо, нравится менять свойство состояния внутри рендера в React, и эта мутация должна происходить вне тела, но как это сделать, если мне нужно MapView внутри тела?

XCode версия 11.3.1 (11C504)

macOS Версия 10.15.4 Beta (19E224g)

1 Ответ

1 голос
/ 28 февраля 2020

Обычное исправление для этого - ожидающая модификация, как показано ниже

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
          DispatchQueue.main.async {
             self.control.showingPlaceDetails = true
          }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...