如何使用 SheetView 函数调用更新 ContentView 中的变量?

Posted

技术标签:

【中文标题】如何使用 SheetView 函数调用更新 ContentView 中的变量?【英文标题】:How to update variables in ContentView with SheetView function call? 【发布时间】: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)
            
            
 
            
        
    

【问题讨论】:

【参考方案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 — 可能很适合提出新问题。 好的,谢谢!我发现问题只是由于我的笔记本电脑速度慢,因为当我在台式机上运行它时,它的运行速度要快得多。但是我仍然认为速度问题仅在代码更改后才出现有点奇怪,但我想这没有问题:)

以上是关于如何使用 SheetView 函数调用更新 ContentView 中的变量?的主要内容,如果未能解决你的问题,请参考以下文章

panGesture iOS 的交互式动画

如何使用 Hibernate con Sql Server 2000 调用存储过程?

如何使用一个类来存储在不同函数中更新的变量,然后在不同的函数中调用这些更新的变量?

如何撤销函数调用访问密钥?

如何使用函数调用正确更新 CGContext?

如何确保更新 reactjs 状态,然后调用函数?