如何在SwiftUI中的视图和子视图之间共享变量

如何在SwiftUI中的视图和子视图之间共享变量,swiftui,Swiftui,我有一个日期选择器,当日期选择值改变时,我想把它存储在一个名为filterSelections的字符串数组中,我该怎么做?提前谢谢 import SwiftUI public var filterSelections: [String: Any]? func setFilterSelections(name: String, selectedValue: Any) { filterSelections[name] = selectedValue } struct myMainSwi

我有一个日期选择器,当日期选择值改变时,我想把它存储在一个名为filterSelections的字符串数组中,我该怎么做?提前谢谢

import SwiftUI
public var filterSelections: [String: Any]?

func setFilterSelections(name: String, selectedValue: Any) {
    filterSelections[name] = selectedValue
}


struct myMainSwiftUIView: View{

    var body: some View {
        ScrollView {
            VStack{
                mySub1View()
            }
        }
    }
}


struct mySub1View: View {
@State public var fromDate: Date = Calendar.current.date(byAdding: DateComponents(year: -40), to: Date()) ?? Date()

    var body: some View {
        HStack(spacing:10) {
            VStack(alignment:.leading, spacing:20) {
            DatePicker(selection: $fromDate, displayedComponents: .date) {
                Text("From")
                    .font(.body)
                    .fixedSize()
            }
                }
            }
        }
    }
    

}

它很简单,创建一个数组并存储所有的数据,不要在代码中增加复杂性,如果您想导出日期数组,然后使用StateObject,这真的不是什么大问题。毕竟,然后开始处理存储阵列,例如,在何处以及如何使用它

import SwiftUI

struct ContentView: View {

    var body: some View {
        
        mySub1View()

    }
}


它很简单,创建一个数组并存储所有的数据,不要在代码中增加复杂性,如果您想导出日期数组,然后使用StateObject,这真的不是什么大问题。毕竟,然后开始处理存储阵列,例如,在何处以及如何使用它

import SwiftUI

struct ContentView: View {

    var body: some View {
        
        mySub1View()

    }
}


对于我来说,很难看到存储对日期选择器的所有更改的应用程序是什么,因为没有任何方法可以取消它们(而且,在iOS 14之前的版本中,我认为当事情发生变化时,轮子会使这个列表看起来特别疯狂)

我的怀疑是,您可能希望将日期与其他一些过滤器一起添加。并且,您指定希望在视图和子视图之间共享该状态,我已尝试适应这种情况。我还使用了您要求的日期格式

我没有像你的问题所说的那样包括
[String:Any]
,而不是字典

这里有很多猜测,因为还不完全清楚你的目标是什么,但希望这能给你一些如何分享状态的想法


class FilterViewModel : ObservableObject {
    @Published var dateFilter : Date = Calendar.current.date(byAdding: DateComponents(year: -40), to: Date()) ?? Date()
    @Published var myOtherFilter = "Filter1"
    
    static var formatter = DateFormatter()
    
    var allFilters : [String] {
        Self.formatter.dateFormat = "yyyy/MM/dd"
        return [myOtherFilter, Self.formatter.string(from: dateFilter)]
    }
}

struct ContentView: View{
    @StateObject private var filterModel = FilterViewModel()
    
    var body: some View {
        ScrollView {
            VStack{
                MySub1View(filterModel: filterModel)
            }
            ForEach(filterModel.allFilters, id: \.self) { filter in
                Text(filter)
            }
        }
    }
}


struct MySub1View: View {
    @ObservedObject var filterModel : FilterViewModel
    
    var body: some View {
        HStack(spacing:10) {
            VStack(alignment:.leading, spacing:20) {
                DatePicker(selection: $filterModel.dateFilter, displayedComponents: .date) {
                    Text("From")
                        .font(.body)
                        .fixedSize()
                }
            }
        }
    }
}


对于我来说,很难看到存储对日期选择器的所有更改的应用程序是什么,因为没有任何方法可以取消它们(而且,在iOS 14之前的版本中,我认为当事情发生变化时,轮子会使这个列表看起来特别疯狂)

我的怀疑是,您可能希望将日期与其他一些过滤器一起添加。并且,您指定希望在视图和子视图之间共享该状态,我已尝试适应这种情况。我还使用了您要求的日期格式

我没有像你的问题所说的那样包括
[String:Any]
,而不是字典

这里有很多猜测,因为还不完全清楚你的目标是什么,但希望这能给你一些如何分享状态的想法


class FilterViewModel : ObservableObject {
    @Published var dateFilter : Date = Calendar.current.date(byAdding: DateComponents(year: -40), to: Date()) ?? Date()
    @Published var myOtherFilter = "Filter1"
    
    static var formatter = DateFormatter()
    
    var allFilters : [String] {
        Self.formatter.dateFormat = "yyyy/MM/dd"
        return [myOtherFilter, Self.formatter.string(from: dateFilter)]
    }
}

struct ContentView: View{
    @StateObject private var filterModel = FilterViewModel()
    
    var body: some View {
        ScrollView {
            VStack{
                MySub1View(filterModel: filterModel)
            }
            ForEach(filterModel.allFilters, id: \.self) { filter in
                Text(filter)
            }
        }
    }
}


struct MySub1View: View {
    @ObservedObject var filterModel : FilterViewModel
    
    var body: some View {
        HStack(spacing:10) {
            VStack(alignment:.leading, spacing:20) {
                DatePicker(selection: $filterModel.dateFilter, displayedComponents: .date) {
                    Text("From")
                        .font(.body)
                        .fixedSize()
                }
            }
        }
    }
}


你的问题我不太清楚。
日期
字符串
的关系如何?日期选择器值将是过滤器选择的一部分。像这样[“fromDate”:2020/01/31]我的错,它不是字符串,而是任何字符串。我更正了它。为什么过滤器是一个类型为
[String:Any]
的字典——会有多个条目吗?可能会,但老实说,这里没有足够的代码让我弄清楚到底应该发生什么。但是,一般来说,如果您在视图之间共享状态,您将使用ObserveObject(通过直接传递或通过环境对象传递)。[String:Any]仍然让我担心——为什么它是
Any
——你不知道过滤了什么吗?也使用
强制展开几乎总是一个坏主意,因为如果变量为nil,它会使程序崩溃。Swift中的类型通常都是大写的。@Michelle:如果您对.onChange或iOS 14.0有异议,那么在相同的工作中使用didSet on selection,我是否应该给您提供示例代码?您的问题我并不清楚。
日期
字符串
的关系如何?日期选择器值将是过滤器选择的一部分。像这样[“fromDate”:2020/01/31]我的错,它不是字符串,而是任何字符串。我更正了它。为什么过滤器是一个类型为
[String:Any]
的字典——会有多个条目吗?可能会,但老实说,这里没有足够的代码让我弄清楚到底应该发生什么。但是,一般来说,如果您在视图之间共享状态,您将使用ObserveObject(通过直接传递或通过环境对象传递)。[String:Any]仍然让我担心——为什么它是
Any
——你不知道过滤了什么吗?也使用
强制展开几乎总是一个坏主意,因为如果变量为nil,它会使程序崩溃。Swift中的类型通常是大写的。@Michelle:如果您对.onChange或iOS 14.0有异议,那么在相同的工作中使用didSet选项,我应该给您提供示例代码吗?