【问题标题】:UIKit update of SwiftUI @State causing "Modifying state during view update"SwiftUI @State 的 UIKit 更新导致“在视图更新期间修改状态”
【发布时间】:2020-06-12 06:54:23
【问题描述】:

我有一个像这样加载 MapKit 的 SwiftUI 组件:

struct AddressView: View {

    @State private var showingPlaceDetails = false

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

MapView 组件是一个使用 UIKit -> SwiftUI 包装技术的 MapKit 结构:

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 属性,该属性将使用 MapView 重新渲染 AddressView。

我理解它为什么不好,比如在 React 中更改渲染内的状态属性,并且这种突变应该发生在身体外部,但是我需要身体内部的 MapView 怎么做?

XCode 版本 11.3.1 (11C504)

macOS 版本 10.15.4 Beta (19E224g)

【问题讨论】:

    标签: swift uikit swiftui


    【解决方案1】:

    通常的解决方法是等待修改,如下所示

        func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
              DispatchQueue.main.async {
                 self.control.showingPlaceDetails = true
              }
        }
    

    【讨论】:

    • 差点从我的桌子上掉下来 :) 这很漂亮,谢谢@Asperi
    • 太棒了!
    猜你喜欢
    • 2022-11-13
    • 2019-12-17
    • 2021-09-17
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 2020-03-11
    • 2020-05-15
    • 1970-01-01
    相关资源
    最近更新 更多