【问题标题】:How to update variables in ContentView with SheetView function call?如何使用 SheetView 函数调用更新 ContentView 中的变量?
【发布时间】:2021-04-19 20:00:44
【问题描述】:

我有一个带有工作表视图和普通视图的代码。当我在工作表视图中按下按钮时,我会进行 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)
            }
            
 
            
        }
    }
}

【问题讨论】:

    标签: arrays swift xcode api swiftui


    【解决方案1】:

    现在,您正在为每个ForEach 调用创建一个 SheetView 实例——它与您在sheet 调用中使用的实例不同。

    要解决此问题,您需要将状态存储在父视图中,并为 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) 或另一个安全检查以确保它们存在。)

    【讨论】:

    • 谢谢!它起作用了,但是现在我的 API 调用非常慢,比以前慢了 10 倍。你知道是什么原因造成的,或者是否有办法解决它?
    • 此更改中的任何内容都不会影响 API 调用的速度——无论哪种方式都只有一个调用完成,而且我没有更改线程或队列。您也没有为您的 API 调用显示任何代码,因此实际上无法进行诊断。我需要看到 minimal reproducible example — 可能很适合提出新问题。
    • 好的,谢谢!我发现问题只是由于我的笔记本电脑速度慢,因为当我在台式机上运行它时,它的运行速度要快得多。但是我仍然认为速度问题仅在代码更改后才出现有点奇怪,但我想这没有问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    • 2020-07-15
    • 1970-01-01
    • 2015-09-27
    • 2019-06-15
    相关资源
    最近更新 更多