我在视图中创建了一个对象,如何将此对象作为 ObservedObject 传递给子视图?
I create an object in a view, how do I pass this object to child views as an ObservedObject?
我正在尝试创建 Recpipe 对象(CoreData 实体),然后在创建该对象后将其传递给 ChildView。执行此操作的最佳方法是什么?
我的第一次尝试是在 MainView 中创建一个 @StateObject,然后将其作为 @ObservedObject 传递给 ChildView,但这似乎只适用于已经存在的对象。 @StateObject 是一个 'get only' 属性 所以我不能根据函数 return 修改它。也许我真的不想在这种情况下创建一个@StateObject?
struct MainView: View {
@State private var presentChildView: Bool = false
@StateObject private var recipe: Recipe = Recipe()
var body: some View {
VStack {
NavigationLink(destination: ChildView(recipe: recipe), isActive: $presentChildView) {
EmptyView()
}
Button("Action", action: {
recipe = functionThatReturnsRecipe()
presentChildView = true
})
}
}
}
struct ChildView: View {
@ObservedObject private var recipe: Recipe
var body: some View {
Text(recipe.title)
}
}
通常你将对象保存在 @State
中,或者更好的是在结构中保存所有 ChildView
的相关变量,这样它就可以独立测试,例如
struct ChildViewConfig {
var recipe: Recipe?
var isPresented = false
mutating func present(viewContext: NSManagedObjectContext) {
recipe = Recipe(context: viewContext)
isPresented = true
}
// might have other save or dismiss mutating funcs here.
}
struct MainView: View {
@Environment(\.managedObjectContext) private var viewContext
@State private var config = ChildViewConfig()
var body: some View {
VStack {
Button("Present") {
config.present(context: viewContext)
}
}
.sheet(isPresented: $config.isPresented, onDismiss: nil) {
ChildView(recipe: config.recipe!)
}
}
}
struct ChildView: View {
@ObservedObject private var recipe: Recipe
var body: some View {
Text(recipe.title)
}
}
使用您可能更喜欢的更高级的 .sheet(item:onDismiss)
,因为它专为编辑项目的这种用例而设计,并允许使用子上下文便签本,因为在设置项目时为 nil 表示如果 sheet 中的编辑被取消,item.childContext
将被丢弃。
在 4:18 in Data Essentials in SwiftUI (WWDC 2020)
了解有关此 @State
Config
结构模式的更多信息
您可以取而代之的是一些应用状态或管理器的概念(任何代表业务逻辑的东西),这将 hold/update 您的食谱,例如
class AppState: ObservableObject {
@Published var recipe: Recipe = Recipe()
func refreshRecipe() {
self.recipe = functionThatReturnsRecipe() // << now works !!
}
private func functionThatReturnsRecipe() -> Recipe {
Recipe()
}
}
struct MainView: View {
@State private var presentChildView: Bool = false
@StateObject private var appState = AppState() // << non-changeable
var body: some View {
VStack {
NavigationLink(destination: ChildView(recipe: appState.recipe), isActive: $presentChildView) {
EmptyView()
}
Button("Action", action: {
appState.refreshRecipe()
presentChildView = true
})
}
}
}
我正在尝试创建 Recpipe 对象(CoreData 实体),然后在创建该对象后将其传递给 ChildView。执行此操作的最佳方法是什么?
我的第一次尝试是在 MainView 中创建一个 @StateObject,然后将其作为 @ObservedObject 传递给 ChildView,但这似乎只适用于已经存在的对象。 @StateObject 是一个 'get only' 属性 所以我不能根据函数 return 修改它。也许我真的不想在这种情况下创建一个@StateObject?
struct MainView: View {
@State private var presentChildView: Bool = false
@StateObject private var recipe: Recipe = Recipe()
var body: some View {
VStack {
NavigationLink(destination: ChildView(recipe: recipe), isActive: $presentChildView) {
EmptyView()
}
Button("Action", action: {
recipe = functionThatReturnsRecipe()
presentChildView = true
})
}
}
}
struct ChildView: View {
@ObservedObject private var recipe: Recipe
var body: some View {
Text(recipe.title)
}
}
通常你将对象保存在 @State
中,或者更好的是在结构中保存所有 ChildView
的相关变量,这样它就可以独立测试,例如
struct ChildViewConfig {
var recipe: Recipe?
var isPresented = false
mutating func present(viewContext: NSManagedObjectContext) {
recipe = Recipe(context: viewContext)
isPresented = true
}
// might have other save or dismiss mutating funcs here.
}
struct MainView: View {
@Environment(\.managedObjectContext) private var viewContext
@State private var config = ChildViewConfig()
var body: some View {
VStack {
Button("Present") {
config.present(context: viewContext)
}
}
.sheet(isPresented: $config.isPresented, onDismiss: nil) {
ChildView(recipe: config.recipe!)
}
}
}
struct ChildView: View {
@ObservedObject private var recipe: Recipe
var body: some View {
Text(recipe.title)
}
}
.sheet(item:onDismiss)
,因为它专为编辑项目的这种用例而设计,并允许使用子上下文便签本,因为在设置项目时为 nil 表示如果 sheet 中的编辑被取消,item.childContext
将被丢弃。
在 4:18 in Data Essentials in SwiftUI (WWDC 2020)
了解有关此@State
Config
结构模式的更多信息
您可以取而代之的是一些应用状态或管理器的概念(任何代表业务逻辑的东西),这将 hold/update 您的食谱,例如
class AppState: ObservableObject {
@Published var recipe: Recipe = Recipe()
func refreshRecipe() {
self.recipe = functionThatReturnsRecipe() // << now works !!
}
private func functionThatReturnsRecipe() -> Recipe {
Recipe()
}
}
struct MainView: View {
@State private var presentChildView: Bool = false
@StateObject private var appState = AppState() // << non-changeable
var body: some View {
VStack {
NavigationLink(destination: ChildView(recipe: appState.recipe), isActive: $presentChildView) {
EmptyView()
}
Button("Action", action: {
appState.refreshRecipe()
presentChildView = true
})
}
}
}