从 datepicker 获取和设置日期,但仍然获得旧的默认值 [英] Fetching and setting date from datepicker, but still getting old default value

查看:30
本文介绍了从 datepicker 获取和设置日期,但仍然获得旧的默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从 DatePicker 获取和设置日期,但我的日期没有更新.SwiftUI 对我来说是新手,我对使用什么类型的属性包装器感到困惑.请在这方面提供帮助并建议何时何地使用 @State, @Binding, @Published 我阅读了一些文章,但仍然不清楚概念给我.

I want to fetch and set date from DatePicker, but my date is not updating. SwiftUI is new to me and I am confused with what type of property wrapper to use. Please help in this and advice when and where to use @State, @Binding, @Published I read some articles but still concept is not clear to me.

这里我使用了 MVVM 和 SwiftUI,我的代码如下.

Here I used MVVM and SwiftUI and my code as follows.

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)

推荐答案

回答关于 SwiftUI 中使用的包装器属性的第二个问题,即 @State、@Binding、@Published.

Reply against your second question about wrapper properties used in SwiftUI i.e @State, @Binding, @Published.

SwiftUI 中最常用的 @Things 是:

The most common @Things used in SwiftUI are:

•   @State - Binding<Value>
•   @Binding - Binding<Value>
•   @ObservedObject - Binding<Value> (*)
•   @EnvironmentObject - Binding<Value> (*)
•   @Published - Publisher<Value, Never>

(*) 从技术上讲,我们得到了一个 Wrapper 类型的中间值,一旦我们将 keyPath 指定为对象内的实际值,它就会变成一个 Binding.因此,如您所见,SwiftUI 中的大多数属性包装器,即负责视图状态的,都被投影"为 Binding,用于在视图之间传递状态.与普通课程不同的唯一包装器是 @Published,但是:1.它是在Combine框架中声明的,而不是在SwiftUI中2.它有不同的目的:使价值可观察3. 它从不用于视图的变量声明,仅用于 ObservableObject 内部考虑 SwiftUI 中这种非常常见的场景,我们声明一个 ObservableObject 并在视图中将其与 @ObservedObject 属性一起使用:

(*) technically, we get an intermediary value of type Wrapper, which turns a Binding once we specify the keyPath to the actual value inside the object. So, as you can see, the majority of the property wrappers in SwiftUI, namely responsible for the view’s state, are being "projected" as Binding, which is used for passing the state between the views. The only wrapper that diverges from the common course is @Published, but: 1. It’s declared in Combine framework, not in SwiftUI 2. It serves a different purpose: making the value observable 3. It is never used for a view’s variable declaration, only inside ObservableObject Consider this pretty common scenario in SwiftUI, where we declare an ObservableObject and use it with @ObservedObject attribute in a view:

class ViewModel: ObservableObject {
    @Published var value: Int = 0
}

struct MyView: View {
    @ObservedObject var viewModel = ViewModel()

    var body: some View { ... }
}

MyView 可以引用 $viewModel.value 和 viewModel.$value - 这两个表达式都是正确的.很混乱,不是吗?这两个表达式最终代表不同类型的值:分别是 Binding 和 Publisher.两者都有实际用途:

MyView can refer to $viewModel.value and viewModel.$value - both expressions are correct. Quite confusing, isn’t it? These two expressions ultimately represent values of different types: Binding and Publisher, respectively. Both have a practical use:

var body: some View {
    OtherView(binding: $viewModel.value)     // Binding
        .onReceive(viewModel.$value) { value // Publisher
            // do something that does not
            // require the view update
        }
}

希望能帮到你.

这篇关于从 datepicker 获取和设置日期,但仍然获得旧的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆