Swiftui 如何在模型对象中使用@Binding var状态更改?
我有一个视图,其中包含一些用于选择日期属性的控件。我想在同级视图模型中使用该date属性在CoreData中搜索该日期的Swiftui 如何在模型对象中使用@Binding var状态更改?,swiftui,Swiftui,我有一个视图,其中包含一些用于选择日期属性的控件。我想在同级视图模型中使用该date属性在CoreData中搜索该日期的Schedule对象,或者在没有的情况下创建一个-asearchOrCreate方法。(我希望我可以使用@FetchRequest来实现这一点,但我还没有找到方法) 我已经将日期设置为@Binding变量,这样我就可以在Child2视图中获得视图更新,但是我还没有找到一种方法将状态更改传递给它的模型,以便它执行搜索或创建,因为didSet不适用于绑定。我是否没有正确地处理这个问
Schedule
对象,或者在没有的情况下创建一个-asearchOrCreate
方法。(我希望我可以使用@FetchRequest
来实现这一点,但我还没有找到方法)
我已经将日期设置为@Binding
变量,这样我就可以在Child2
视图中获得视图更新,但是我还没有找到一种方法将状态更改传递给它的模型,以便它执行搜索或创建
,因为didSet
不适用于绑定。我是否没有正确地处理这个问题,是否应该使用@Environment
变量或其他什么
struct ParentView: View {
@State var day: Date = Date().noon
var body: some View {
VStack() {
Child1View(day: $day)
Child2View(day: day)
}
}
}
struct Child1View: View {
@Binding var day: Date
// code to select day
}
struct Child2View: View {
var day: Date // I do not need to update the day in this view,
//just display it and use it in an object, so I did not use @Binding
@StateObject private var viewModel = Child2ViewModel()
...
}
class Child2ViewModel: ObservableObject {
var day: Date {
didSet {
// call searchOrCreate in CoreData for the Schedule object
}
@Published var schedule: Schedule
}
我发现,如果我将viewModel作为父视图的一部分并将其传递下去,那么它会破坏封装。理想情况下,我希望Child2View
只需获得一个约会,然后从那里开始做它的事情
struct ParentView: View {
@StateObject var viewModel = Child2ViewModel()
var body: some View {
VStack() {
Child1View(day: $viewModel.day)
Child2View(viewModel: viewModel)
}
}
}
struct Child2View: View {
@ObservedObject private var viewModel: Child2ViewModel
...
}
class Child2ViewModel: ObservableObject {
@Published var day = Date().noon {
didSet {
// call searchOrCreate in CoreData for the Schedule object
}
@Published var schedule: Schedule
}
您可以使用
onReceive
捕获父变量的更改并将其传递给ViewModel:
import Combine
import SwiftUI
struct ParentView: View {
@State var day: Date = Date()
var body: some View {
VStack {
Child1View(day: $day)
Child2View(day: day)
}
}
}
struct Child2View: View {
@StateObject private var viewModel = Child2ViewModel()
var day: Date
var body: some View {
Text("Child2View")
.onReceive(Just(day)) { // whenever the parent `day` changes, update the viewModel
guard viewModel.day != $0 else { return }
viewModel.day = $0
}
}
}
我试过了,它似乎进入了一个无限循环?我想这是因为
viewModel.day
有一个didSet
,它更新@发布的日程安排
,这会导致Child2View
被重新绘制,从而@绑定
再次接收。@SebastianVancea是的,onReceive
在初始化视图时也会被触发。您可以添加一个guard语句来检查值是否更改-查看更新的答案。视图将被重绘两次似乎是多余的,一次是在日更新,一次是在@发布的计划中,但我想这不是一个大问题。但是,为什么需要在Child2View
中绑定一天?我不需要在该视图中对它进行任何更新,它看起来像。onReceive被调用,即使它是一个简单的变量。@SebastianVancea我没有注意到它-是的,如果不更改值,那么它就不必是@Binding
。