如何在视图启动之前在 SwiftUI 中加载更新的变量?

Posted

技术标签:

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

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

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

我想要做的是以下

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

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

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

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 属性 【参考方案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。

以上是关于如何在视图启动之前在 SwiftUI 中加载更新的变量?的主要内容,如果未能解决你的问题,请参考以下文章

在列表中加载 WebView 而无需重新加载 webView 内容 SwiftUI

在 SwiftUI 中加载网站时加载活动指示器

如何在 UITabBarController 中加载所有视图?

URLImage 从不在 SwiftUI 的小部件应用程序中加载图像 [重复]

如何根据要求在 Kendo Window 中加载部分视图

如何在 AdminLte 多选下拉列表中加载项目以进行更新 - Laravel 8