SwiftUI 将选定日期从模态传递给父变量

SwiftUI passing selected date from modal to parent variables

需要这方面的帮助。

我有一个包含 2 个日期变量的视图,我想显示一个带有日期选择器的模式,让用户为这些变量选择不同的日期。

目前我有两个按钮显示相同 sheet 但将不同的变量传递给模态。 关闭模态后变量不更新的问题


import SwiftUI

@main
struct MyApp: App {
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}


import SwiftUI

struct ContentView: View {
    
    @State private var secOneDate = Date()
    @State private var secTwoDate = Date()
    @State private var isDatepickerPresented = false
    
    var body: some View {
        VStack {
            HStack{
                Button{
                    isDatepickerPresented = true
                } label: {
                    Image(systemName: "calendar")
                        .imageScale(.large)
                        .foregroundColor(.indigo)
                        
                }
                .sheet(isPresented: $isDatepickerPresented){
                    DatePickView(selectDate: $secOneDate)
                }
                
                Text("SecOneDate: \(secOneDate.formatted(date: .abbreviated, time: .shortened))") 
            }
            .padding()
            
            HStack{
                Button{
                    isDatepickerPresented = true
                } label: {
                    Image(systemName: "calendar")
                        .imageScale(.large)
                        .foregroundColor(.mint)
                    
                }
                .sheet(isPresented: $isDatepickerPresented)
                { 
                    DatePickView(selectDate: $secTwoDate)
                }
                Text("SecTwoDate: \(secTwoDate.formatted(date: .abbreviated, time: .shortened))") 
            }
            .padding()
            
        }
    }
}


import SwiftUI

struct DatePickView: View {
    
    @Environment(\.dismiss) private var dismiss
    @Binding var selectDate: Date
    
    var body: some View {
        VStack(alignment: .center, spacing: 20) {
            HStack {
                Text("\(selectDate)")
                    .padding()
                
                Spacer()
                Button {
                    dismiss()
                } label: {
                    Image(systemName: "delete.backward.fill")
                        .foregroundColor(.indigo)
                }
                
            }.padding()
            
            
            DatePicker("", selection: $selectDate)
                .datePickerStyle(.graphical)
            
        }
    }
}

首先,感谢您提供最小的、可重现的示例:它很清楚,可以立即用于调试。回答你的问题:

您的代码存在的问题是您只有一个变量可以打开两个日期的 sheet。即使您正确地传递了两个不同的 @Bindings,当您切换 isDatepickerPresented 时,您要求 SwiftUI 显示 both sheets,但这永远不会发生。在不知不觉中,您总是触发 sheet 演示文稿的 第一个 - 绑定 secOneDate 的演示文稿。绑定 secTwoDate 的 sheet 永远不会显示,因为您不能同时拥有两个 sheet。

了解了这一点,解决方案就很简单了:使用两个不同的触发变量。这是更正后的代码(DatePickView 没有改变):

struct Example: View {
    
    @State private var secOneDate = Date()
    @State private var secTwoDate = Date()
    @State private var isDatepickerOnePresented = false
    @State private var isDatepickerTwoPresented = false

    var body: some View {
        VStack {
            HStack{
                Button{
                    isDatepickerOnePresented = true
                } label: {
                    Image(systemName: "calendar")
                        .imageScale(.large)
                        .foregroundColor(.indigo)
                        
                }
                .sheet(isPresented: $isDatepickerOnePresented){
                    DatePickView(selectDate: $secOneDate)
                }
                
                Text("SecOneDate: \(secOneDate.formatted(date: .abbreviated, time: .shortened))")
            }
            .padding()
            
            HStack{
                Button{
                    isDatepickerTwoPresented = true
                } label: {
                    Image(systemName: "calendar")
                        .imageScale(.large)
                        .foregroundColor(.mint)
                    
                }
                .sheet(isPresented: $isDatepickerTwoPresented) {
                    DatePickView(selectDate: $secTwoDate)
                }
                Text("SecTwoDate: \(secTwoDate.formatted(date: .abbreviated, time: .shortened))")
            }
            .padding()
            
        }
    }
}