【问题标题】:How to load updated variable in SwiftUI before view initiation?如何在视图启动之前在 SwiftUI 中加载更新的变量?
【发布时间】:2021-08-08 19:18:17
【问题描述】:

我正在构建一个 SwiftUI 应用程序,但我被初始值卡住了,我为启动提供了一个变量,并且在我加载视图时它不会更新。

我已尝试寻找一些答案,但对我的代码没有任何帮助。

我想要做的是以下

  1. 我有一个包含位置的数据集
  2. 我想创建这些位置的子集
  3. 我想从新创建的子集中加载第一个位置

我遇到的问题是,一旦我第一次加载地图,它仍然会保留初始数据,而不是子集中的数据

任何帮助表示赞赏, 丹尼尔

import SwiftUI
import CoreData
import MapKit
struct MainInterface: View {
    @Environment(\.presentationMode) var presentationMode
    var initialPoint: Places = totalData[1]
    init() {
        let subset1 = Array(Set(totalData.filter({
            $0.Area == 1
        })))
        .prefix(3)
        let subset2 = Array(Set(totalData.filter({
            $0.Area == 2
        })))
        .prefix(3)
        levelSet = Array(subset1) + Array(subset2)
        self.initialPoint = levelSet[0]
    }

    var body: some View {
        VStack(spacing: 0) {
            SubView(initialPoint: $initialPoint)
        }
        .onAppear{
            //levelSet = Array(level1set) + Array(level2set)
            //self.initialPoint = levelSet[0]
        }
    }

}


import SwiftUI
import MapKit
struct SubView: UIViewRepresentable {
    @Binding var initialPoint: Place
    let mapView = MKMapView()
    func makeUIView(context: Context) -> MKMapView {
        mapView.delegate = context.coordinator
        return mapView
    }

    func updateUIView(_ view: MKMapView, context: Context) {
    }

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

    class Coordinator: NSObject, MKMapViewDelegate, UIGestureRecognizerDelegate {
        var parent: SubView
        init(_ parent: SubView) {
            self.parent = parent
            super.init()
            self.parent.mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: self.parent.initialPoint.Latitude, longitude: self.parent.initialPoint.Longitude), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)), animated: true)
        }
    }

    func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
        parent.region = mapView.region
        parent.centerCoordinate = mapView.centerCoordinate
    }

}

【问题讨论】:

  • 鼓励您将init 方法中的内容放入视图模型并使用observable 模式。否则 initialPoint 应该是 @State 属性

标签: swift swiftui mapkit


【解决方案1】:

这里有几个问题。首先,structs 不能正常修改,所以不能修改它们的变量。这就是为什么我们有@State 属性包装器等,以允许更改变量。但是,简单地将initialPoint 变量更改为@State 并不能解决所有问题。在您给出的代码中,您似乎已经删除了很多东西,因为您引用了未在 MainInterface 中初始化的变量,但是您所显示的内容不应该编译,因为您试图传递一个标准变量 @ 987654328@$`。这需要一个包装变量才能使用。

有了你给我们的,我会这样初始化结构:

struct MainInterface: View {
    @Environment(\.presentationMode) var presentationMode
    // make this @State if you need to pass it to a binding.
    @State var initialPoint: Places 
    init(totalData: TotalData) { //I have know idea what the `Type` of totalData is
    //as you never defined it in the struct. Substitute its actual `Type` here.
        let subset1 = Array(Set(totalData.filter({
            $0.Area == 1
        })))
        .prefix(3)
        let subset2 = Array(Set(totalData.filter({
            $0.Area == 2
        })))
        .prefix(3)
        levelSet = Array(subset1) + Array(subset2)
        // This will initialize `initialPoint` as a State variable
        _initialPoint = State(initialValue: levelSet[0])
        // It seems to me that you have gone to a great deal of trouble to initialize
        // `initialPoint` to be the first element in the `subset1` array slice. I am not
        // sure what the point of creating your array slice as it is never used outside
        // of the `init()`
    }

我将从Apple's SwiftUI tutorials 开始,以便您开始感受。那里涵盖了这种确切的情况,但您将了解它的工作方式和原因。

【讨论】:

  • 这对我不起作用:/我将努力提供完整的代码集以复制问题。
  • 我们不想要完整的代码集。我们想要一个Minimal, Reproducible Example
猜你喜欢
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
相关资源
最近更新 更多