我有一个由 NavigationLink 呈现的编辑视图。它需要一个配方,该配方保存在具有一系列它们的管理器中。
应用程序代码(复制意大利面应该运行):
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// VIEWS
//
struct ContentView: View {
@StateObject var recipeManager = RecipeManager()
@State var editingRecipeIndex: Int?
@State var showEditView = false
var body: some View {
NavigationView {
ZStack {
if let index = editingRecipeIndex {
// THIS LINK SEEMS TO NOT HOOK UP CORRECTLY ***
NavigationLink(destination: RecipeEditView(recipe: $recipeManager.recipes[index]), isActive: $showEditView, label: {
EmptyView()
}).buttonStyle(PlainButtonStyle())
}
List(recipeManager.recipes, id: \.self) { recipe in
NavigationLink(
destination: RecipeDetailView(recipe: recipe),
label: {
Text(recipe.title.isEmpty ? "New Recipe" : recipe.title)
})
}
.navigationTitle("My Recipes")
.listStyle(GroupedListStyle())
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
recipeManager.recipes.append(Recipe())
editingRecipeIndex = recipeManager.recipes.count - 1
showEditView = true
}, label: {
Image(systemName: "plus")
})
}
}
}
}
.environmentObject(recipeManager)
}
}
struct RecipeDetailView: View {
var recipe: Recipe
var body: some View {
VStack {
Text(recipe.title)
.font(.title)
.padding(.top)
Text(recipe.description)
.fixedSize(horizontal: false, vertical: true)
}
}
}
struct RecipeEditView: View {
@Binding var recipe: Recipe
@Environment(\.presentationMode) var presentationMode
var body: some View {
Form {
TextField("Enter your recipe title", text: $recipe.title)
TextField("Enter a description", text: $recipe.description)
Text("Title: \(recipe.title)")
Text("Description: \(recipe.description)")
Button("Save") {
presentationMode.wrappedValue.dismiss()
}
}
}
}
// MODELS
//
class RecipeManager: ObservableObject {
@Published var recipes: [Recipe] = [
Recipe(title: "one", description: "one-one"),
Recipe(title: "two", description: "two-two"),
Recipe(title: "three", description: "three-three")
]
}
struct Recipe: Identifiable, Hashable, Equatable {
let id: UUID
var imageName: String
var title: String
var description: String
var steps: [String] // [RecipeStep]
static func == (lhs: Recipe, rhs: Recipe) -> Bool {
return lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
init(id: UUID = UUID(), imageName: String = "croissant", title: String = "", description: String = "", steps: [String] = []) {
self.id = id
self.imageName = imageName
self.title = title
self.description = description
self.steps = steps
}
}
重现步骤:
- 添加一个新配方,这将带您进入编辑表单。
- 输入标题,后跟描述,请注意绑定似乎适用于此上下文中的其他文本字段。
- 保存,带您返回列表视图。
- 点击新食谱并注意缺少描述。
如果我在标题之前输入描述,两者都会在绑定到视图的模型上得到更新。但是,如果我在标题之后输入描述,则只保存标题。我是否显示/隐藏键盘或更改字段焦点似乎并不重要。即使我向Recipe
模型添加更多属性,字段之后的每个字段都会存在相同的行为title
......帮助?!