首页 > 解决方案 > 如何使用 SheetView 函数调用更新 ContentView 中的变量?

问题描述

我有一个带有工作表视图和普通视图的代码。当我在工作表视图中按下按钮时,我会进行 API 调用。然后,此 API 调用会更新一些我试图使用“ForEach”在常规视图中显示的变量。但是,当我在工作表视图中进行调用并将其关闭时,数组似乎没有在我的正常视图中更新。我的视图仍然是空白的(除了显示“显示工作表”的按钮。如何更新数组以使其不为空白?

这是我的常规观点:

 
// MARK: - Schedule View
struct ScheduleView: View {
    @State var selectedTab = 0
    @State private var showingSheet = true

    var body: some View {
        GeometryReader { geo in
            VStack {
                ForEach(SheetView().vm.Trips, id: \.self) { dict in
                    Text(dict["Origin"]!) // I want this varible to update, but I doesn't
                    Text(dict["Destination"]!) // It instead remains blank
                }
                Button("Show sheet") {
                    showingSheet.toggle()
                }
                .sheet(isPresented: $showingSheet) {
                    SheetView()
                }
                .frame(width: geo.size.width*0.7, height: geo.size.height*0.06)
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(11)
                .position(x: geo.size.width/2, y: geo.size.height/2)
                // MARK: - Padding funkar inte
                
            }
            
        }.padding()
    }
}

这是我的工作表视图:

struct SheetView: View {
    @Environment(\.presentationMode) var presentationMode
    
    @StateObject var vm: PlanTripViewModel = PlanTripViewModel()
    @State var selected = 0
    
    var body: some View {
        GeometryReader {geo in
            ZStack{
                VStack {
                    TextField("From", text: $vm.origin.input).padding()
                    TextField("To", text: $vm.dest.input).padding()
                    TextField("00:00", text: $vm.arrivalTime).padding()
                    TextField("yyyy-mm-dd", text: $vm.travelDate).padding()
    
                    Button("Add trip") {
                        vm.fetchStatus = .start // This starts the API call in another file of mine
                        presentationMode.wrappedValue.dismiss() // This closes the sheet view
                    }.padding()
                }.foregroundColor(.blue)
            }
            
 
            
        }
    }
}

标签: arraysswiftxcodeapiswiftui

解决方案


现在,您在每次调用时都创建一个 实例——它与您在调用中使用的实例不同。SheetViewForEachsheet

要解决这个问题,您需要将状态存储在父视图中并为sheet视图提供对其的引用。

struct SheetView: View {
    @Environment(\.presentationMode) var presentationMode
    
    @ObservedObject var vm: PlanTripViewModel //<-- Here
    @State var selected = 0
    
    var body: some View {
        GeometryReader {geo in
            ZStack{
                VStack {
                    TextField("From", text: $vm.origin.input).padding()
                    TextField("To", text: $vm.dest.input).padding()
                    TextField("00:00", text: $vm.arrivalTime).padding()
                    TextField("yyyy-mm-dd", text: $vm.travelDate).padding()
    
                    Button("Add trip") {
                        vm.fetchStatus = .start // This starts the API call in another file of mine
                        presentationMode.wrappedValue.dismiss() // This closes the sheet view
                    }.padding()
                }.foregroundColor(.blue)
            }
            
 
            
        }
    }
}

struct ScheduleView: View {
    @State var selectedTab = 0
    @State private var showingSheet = true
    @StateObject var vm: PlanTripViewModel //<-- Here

    var body: some View {
        GeometryReader { geo in
            VStack {
                ForEach(vm.Trips, id: \.self) { dict in
                    Text(dict["Origin"]!)
                    Text(dict["Destination"]!)
                }
                Button("Show sheet") {
                    showingSheet.toggle()
                }
                .sheet(isPresented: $showingSheet) {
                    SheetView(vm: vm) //<-- Here
                }
                .frame(width: geo.size.width*0.7, height: geo.size.height*0.06)
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(11)
                .position(x: geo.size.width/2, y: geo.size.height/2)
                // MARK: - Padding funkar inte
                
            }
            
        }.padding()
    }
}

!(注意:您可能已经知道这一点,但是如果键不存在,强制解包字典值会导致崩溃。您可能需要使用可选绑定 ( if let) 或其他安全检查来确保它们存在。)


推荐阅读