我有一个简单的
NavigationSplitView
用户可以从人列表中进行选择,然后在内容列中出现了他们喜欢的书籍的披露组,然后他们可以选择当前正在阅读的书。但是,当我将称为@State
作为绑定到披露组视图struct结构的throups thert时,当我选择新阅读器时,它不会更新。这是一个视频:https://youtube.com/shorts/j96upqx9_ru?feature =share和代码:
selectedBook
我的第一个想法是,这是苹果发行说明的东西:
navigationsplitview列中的条件视图无法更新 一些状态变化。 (91311311)解决方法:包裹内容 ZSTACK中的列。
我已经在代码中的许多方面尝试过这一点,但这没有什么区别。根据我的阅读,我认为我可能需要使用而不是
import SwiftUI import SwiftData @Model class Person { var name: String = "" @Relationship(deleteRule: .cascade, inverse: \Book.customer) var books: [Book]? init(name: String) { self.name = name } } @Model class Book { var name: String = "" var customer: Person? init(name: String) { self.name = name } } struct MainView: View { @Environment(\.modelContext) private var modelContext @Query private var queriedPersons: [Person] @State private var columnVisibility: NavigationSplitViewVisibility = .automatic @State private var selectedPerson: Person? var body: some View { NavigationSplitView(columnVisibility: self.$columnVisibility) { List(selection: self.$selectedPerson) { ForEach(self.queriedPersons) { customer in NavigationLink(customer.name, value: customer) } } .listStyle(.insetGrouped) } content: { if let selectedPerson = self.selectedPerson { PersonView(selectedPerson: selectedPerson) } } detail: { // Left out to simplify code EmptyView() } .task { do { try modelContext.delete(model: Person.self) let billPerson = Person(name: "Bill") self.modelContext.insert(billPerson) billPerson.books = [ Book(name: "Catcher in the Rye"), Book(name: "Liar's Poker"), Book(name: "The Odyssey") ] let mikePerson = Person(name: "Mike") self.modelContext.insert(mikePerson) mikePerson.books = [ Book(name: "Red Dragon"), Book(name: "Steve Jobs"), Book(name: "The Great Gatsby") ] } catch { fatalError(error.localizedDescription) } } .onFirstAppear { self.columnVisibility = .all } } } struct PersonView: View { private(set) var selectedPerson: Person // Both selectedBook and booksBinding are declared in PersonView because I use them here in the actual code @State private var selectedBook: Book? var booksBinding: Binding<[Book]?> { Binding<[Book]?>( get: { self.selectedPerson.books }, set: { self.selectedPerson.books = $0 } ) } var body: some View { List { BooksDisclosure(books: self.booksBinding, selectedBook: self.$selectedBook) } .listStyle(.insetGrouped) } } struct BooksDisclosure: View { @Binding var books: [Book]? @Binding var selectedBook: Book? @Query private var queriedBooks: [Book] @State var disclosureIsExpanded: Bool = false // Have to get the values this way so it updates in real-time in CloudKit private var filteredAndSortedBooks: [Book] { return self.queriedBooks .filter { book in self.books?.contains(book) == true } .sorted { lhs, rhs in lhs.name.localizedCaseInsensitiveCompare(rhs.name) == .orderedAscending } } var body: some View { DisclosureGroup(isExpanded: self.$disclosureIsExpanded) { ForEach(self.filteredAndSortedBooks) { book in HStack { Button(action: { if self.selectedBook != book { self.selectedBook = book } if self.disclosureIsExpanded != true { self.disclosureIsExpanded = false } }) { Text(book.name) } .buttonStyle(PlainButtonStyle()) if self.selectedBook == book { Image(systemName: "checkmark") } Spacer() } } } label: { Text("Currently Reading: ") if let selectedBook = self.selectedBook { Text(selectedBook.name) } else { Text("None") } } .onAppear { self.selectedBook = self.filteredAndSortedBooks.first } } }
@Bindable
@Binding
(显然是iOS 17次,需要以selectedBook
而不是aBooksDisclosure
的方式将其传递给),但是,当我更改它时,所有的地狱都会随编译器而散开。显然,它不再是可选的,并且不了解适当的语法,无法将其从可选的可选转换为非可选元素,并且当我尝试分配它时会抛出错误(但@Bindable
行不起作用)。甚至不确定我对此迈向正确的方向。
一般只是想知道,当我切换到@Binding
时,当我切换到wrappedValue
时,是否有人对为什么现在不起作用有任何洞察力。
尝试这种方法将
NavigationSplitView
传递给其他观点。 注意,因为您使用的是计算属性
NavigationStack
您需要自己更新视图(请参阅新的
selectedPerson
位置)。
请注意,如果您想记录
一个人选择了,然后将其包括在您的.onAppear