【发布时间】:2020-10-19 08:00:21
【问题描述】:
我的内容视图是一个由解码的 json 数组填充的表单,如下所示:
struct ContentView: View {
@State var bookData: [Book] = load("list")
@State private var selectedBook: Book? = nil
@State private var active = false
var body: some View {
NavigationView {
Form {
ForEach(bookData){ bookDetail in
BookView(book: bookDetail)
.background(
NavigationLink(destination: EditBook(bookData: $bookData, book: bookDetail), tag: bookDetail, selection: $selectedBook) {
EmptyView()
}
)
.contextMenu{
Button(action: {
//delete action here
}) {
Label("Delete", systemImage: "trash")
}
}
}
}
.navigationBarTitle("Books")
.navigationBarItems(trailing: NavigationLink(destination: NewBook(bookData: $bookData)){Image(systemName: "plus.circle").font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)})
}
}
}
我的应用程序现在的工作方式是 NewBook 和 Edit 图书视图对我的 bookData 数组有一个 binder 属性。要将新书添加到数组中,NewBook 视图只需将 bookData 附加到另一个结构并使用 writeJSON(bookData) 对其进行编码。同样,在内容视图中,我想使用上下文菜单删除一个元素并重新编码已编辑的数组。对于 editBook 视图,我想编辑一个结构并使用 writeJSON 对其进行编码。
这是我的 editBook 视图:
struct EditBook: View {
@Binding var bookData: [Book]
@State private var name = ""
@State private var author = ""
@State private var page = ""
@State private var total = ""
var book: Book
var body: some View {
Form{
Section(header: Text("Change the details of the book")){
HStack{
Text("Name:")
TextField(book.name, text: $name)
}
HStack{
Text("Author:")
TextField(book.author, text: $author)
}
HStack{
Text("Page number:")
TextField(book.page, text: $page)
.keyboardType(.numberPad)
}
HStack{
Text("Number of pages:")
TextField(book.total, text: $total)
.keyboardType(.numberPad)
}
}
Section{
HStack{
Spacer()
Button(action: {
}) {
Text("Update book")
}
Spacer()
}
}
}
.navigationTitle("Edit Book")
}
}
这是有效的 NewBook 视图(供参考)
struct NewBook: View {
@Binding var bookData: [Book]
@State private var name = ""
@State private var author = ""
@State private var page = ""
@State private var total = ""
var body: some View {
Form{
Section(header: Text("Enter the details of the book")){
TextField("Title", text: $name)
TextField("Author", text: $author)
TextField("Current page number", text: $page)
.keyboardType(.numberPad)
TextField("Total number of pages", text: $total)
.keyboardType(.numberPad)
}
Section{
HStack{
Spacer()
Button(action: {
bookData.append(Book(id: UUID(), name: name, author: author, page: page, total: total, image: "string"))
writeJSON(bookData)
}) {
Text("Add book")
}
Spacer()
}
}
}
.navigationTitle("New Book")
}
}
我尝试在内容视图中使用bookData.removeAll(where: {bookData.contains(bookDetail)}),但删除了所有内容。
【问题讨论】:
-
我将从重构以使用模型对象开始。该对象应包含您的书籍数组以及处理序列化/反序列化。你可以让你的书符合
identifiable(或者至少有一个唯一的标识符),这样你的模型就可以轻松识别正在编辑的书 -
@Paulw11 这本书的结构已经符合可识别的 uuid,我不明白为什么我应该将数组变成一个结构(我能想到的唯一原因是结构包含我的编码和解码功能)
-
没错。编码和解码等业务逻辑属于你的模型,而不是你的视图。事实上,我可能会把它变成一个类而不是一个结构。
-
@Paulw11 会提高性能,有什么好处?
-
这与性能无关。这是关于建筑的。通过使用作为类的模型对象,您可以获得可变性、引用语义和 ObservableObject 支持。在 SwiftUI 中,您的视图中应该几乎没有程序代码