Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swiftui 从datepicker获取和设置日期,但仍获取旧的默认值_Swiftui - Fatal编程技术网

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
        }
}