Swiftui 从datepicker获取和设置日期,但仍获取旧的默认值
我想从Swiftui 从datepicker获取和设置日期,但仍获取旧的默认值,swiftui,Swiftui,我想从日期选择器获取并设置日期,但我的日期未更新。SwiftUI对我来说是新的,我不知道应该使用什么类型的属性包装器。请在这方面提供帮助,并建议何时何地使用@State,@Binding,@Published我读了一些文章,但仍然不清楚这些概念 这里我使用了MVVM和SwiftUI,我的代码如下 class MyViewModel:ObservableObject { @Published var selectedDate : Date = Date() @Published v
日期选择器
获取并设置日期,但我的日期未更新。SwiftUI对我来说是新的,我不知道应该使用什么类型的属性包装器。请在这方面提供帮助,并建议何时何地使用@State
,@Binding
,@Published
我读了一些文章,但仍然不清楚这些概念
这里我使用了MVVM和SwiftUI,我的代码如下
class MyViewModel:ObservableObject {
@Published var selectedDate : Date = Date()
@Published var selectedDateStr : String = Date().convertDateToString(date: Date())
}
struct DatePickerView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@ObservedObject var viewModel : MyViewModel
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}
@State private var selectedDate = Date()
var body: some View {
VStack {
//Title
HStack{
Text("SELECT A DATE")
.foregroundColor(.white)
.font(.system(size: 20))
}
.frame(width:UIScreen.main.bounds.width,height: 60)
.background(Color.red)
//Date Picker
DatePicker(selection: $selectedDate, in: Date()-15...Date(), displayedComponents: .date) {
Text("")
}.padding(30)
Text("Date is \(selectedDate, formatter: dateFormatter)")
Spacer()
//Bottom buttons
Text("DONE")
.fontWeight(.semibold)
.frame(width:UIScreen.main.bounds.width/2,height: 60)
.onTapGesture {
self.viewModel.selectedDate = self.selectedDate
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
//calling:
DatePickerView(viewModel: self.viewModel)
类MyViewModel:ObserveObject{
@已发布变量selectedDate:Date=Date()
@已发布的变量selectedDateStr:String=Date().convertDateToString(日期:Date())
}
结构DatePickerView:视图{
@环境(\.presentationMode)变量presentationMode:绑定
@ObservedObject var viewModel:MyViewModel
var dateFormatter:dateFormatter{
let formatter=DateFormatter()
formatter.dateStyle=.long
返回格式化程序
}
@State private变量selectedDate=Date()
var body:一些观点{
VStack{
//头衔
HStack{
文本(“选择日期”)
.foregroundColor(.白色)
.font(.system(大小:20))
}
.frame(宽度:UIScreen.main.bounds.宽度,高度:60)
.背景(颜色.红色)
//日期选择器
日期选择器(选择:$selectedDate,in:Date()-15…Date(),displayedComponents:.Date){
正文(“”)
}.填充(30)
文本(“日期为\(选定日期,格式化程序:日期格式化程序)”)
垫片()
//底部按钮
文本(“完成”)
.fontWeight(.半加粗)
.frame(宽度:UIScreen.main.bounds.width/2,高度:60)
.ontapsigne{
self.viewModel.selectedDate=self.selectedDate
self.presentationMode.wrappedValue.discouse()文件
}
}
}
}
//电话:
DatePickerView(视图模型:self.viewModel)
您可以使用以下公式计算当前日期-15天
:
let previousDate = Calendar.current.date(byAdding: .day, value: -15, to: Date())!
然后在日期选择器的范围内使用以前的日期:
DatePicker(selection: $selectedDate, in: previousDate...Date(), displayedComponents: .date) { ...
总之,您的代码可以如下所示:
struct DatePickerView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var viewModel: MyViewModel
var dateFormatter: DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter
}
@State private var selectedDate = Date()
let previousDate = Calendar.current.date(byAdding: .day, value: -15, to: Date())!
var body: some View {
VStack {
//Title
HStack{
Text("SELECT A DATE")
.foregroundColor(.white)
.font(.system(size: 20))
}
.frame(width:UIScreen.main.bounds.width,height: 60)
.background(Color.red)
//Date Picker
DatePicker(selection: $selectedDate, in: previousDate...Date(), displayedComponents: .date) {
Text("")
}.padding(30)
Text("Date is \(selectedDate, formatter: dateFormatter)")
Spacer()
//Bottom buttons
Button(action: {
self.viewModel.selectedDate = self.selectedDate
self.presentationMode.wrappedValue.dismiss()
}) {
Text("DONE")
.fontWeight(.semibold)
}
}
}
}
在Xcode 11.5、Swift 5.2.4中测试。回答关于SwiftUI中使用的包装器属性的第二个问题,即@State、@Binding、@Published SwiftUI中最常用的@东西是:
• @State - Binding<Value>
• @Binding - Binding<Value>
• @ObservedObject - Binding<Value> (*)
• @EnvironmentObject - Binding<Value> (*)
• @Published - Publisher<Value, Never>
MyView可以引用$viewModel.value和viewModel.value-这两个表达式都是正确的。很混乱,不是吗?
这两个表达式最终表示不同类型的值:Binding和Publisher。
两者都有实际用途:
var body: some View {
OtherView(binding: $viewModel.value) // Binding
.onReceive(viewModel.$value) { value // Publisher
// do something that does not
// require the view update
}
}
希望它可以帮助您。我的问题是我的日期没有更新,它仍然返回我最初分配的值。请帮我说说你到底在说哪个
date
变量?哪个变量在访问时没有更新?在这段代码中,除了当前日期之外,我无法选择任何其他日期。意思是我只能选择今天日期,即self.SelectedDate我测试了答案中的DatePickerView
。我这样使用它:DatePickerView(viewModel:MyViewModel())
在我的主视图主体中。如果您遇到一些其他问题,可能是由于您如何表达您的观点。请分享更多的代码,这样我可以帮助你。
var body: some View {
OtherView(binding: $viewModel.value) // Binding
.onReceive(viewModel.$value) { value // Publisher
// do something that does not
// require the view update
}
}