我在modelContext中插入了一个新项(在单个Deck上),视图应该自动更新,但它没有。仅当我从单个Deck视图导航回Deck视图列表时,它才会刷新。我不知道我在这里做错了什么。
- 当我从牌组中删除一张牌时,它也不起作用
- 这看起来像是我在传递一个值而不是一个引用。但我找不到地点**
我的视图结构看起来像这样:
- 甲板视图(甲板列表)
- 牌组视图(牌组中的牌列表-我正在从该视图添加新牌)
- 卡片视图(单卡)
private func addCard() {
let newCard = Card(
front: front,
deck: cardModel.deck!
)
withAnimation {
modelContext.insert(newCard)
}
}
CardModel存储卡片组(在尝试将新的Card插入上下文之前,我确保卡片组不为nil):
@Observable
final class CardModel {
var deck: Deck? = nil
public func showAddSheet(deck: Deck) -> Void {
self.deck = deck
}
}
甲板型号:
@Model
final class Deck {
@Relationship(.cascade)
var cards: [Card]? = [Card]()
var name: String = ""
init(name: String) {
self.cards = [Card]()
self.name = name
}
}
卡片型号:
@Model
final class Card {
@Relationship(inverse: \Deck.cards)
var deck: Deck? = nil
var front: String = ""
init(front: String, deck: Deck) {
self.deck = deck
self.front = front
}
}
路由器类别:
enum Path: Hashable {
case decks
case deck(Deck)
}
@Observable
final class RouterModel {
var path: [Path] = [Path]()
}
甲板视图:
struct DecksView: View {
@Query() var decks: [Deck]
var body: some View {
List {
NavigationStack(path: $routerModel.path) {
ForEach(decks, id: \.self) { deck in
NavigationLink(value: Path.deck(deck)) {
Text(deck.name)
}
}
}
}
.navigationDestination(for: Path.self, destination: { path in
switch path {
case .decks:
DecksView()
case let .deck(deck):
DeckView(deck: deck)
case let .card(card):
CardView(card: card)
}
})
}
}
甲板视图:
struct DeckView: View {
var deck: Deck
var body: some View {
List {
ForEach(cards) { card in
VStack {
Text(card.front)
}
}
}
}
}
2条答案
按热度按时间gmxoilav1#
SwiftUI中的视图是一种“静态”的,并且在视图渲染周期中由系统多次构造,销毁和重建。
为了在这个过程中非常快速,所有SwiftUI视图都是
struct
,根据定义,Swift中的结构体总是通过复制传递其值。在设计SwiftUI应用程序时请记住这一点。在您的例子中,
DeckView
没有任何线索表明它是更大架构的一部分,并且deck
属性可能会更改。只有DecksView
具有此上下文。一旦它导航到DeckView
子视图,视图就不会接收更新,并且DecksView
沿着属性可能会在它离开前台时立即被销毁。一个很好的替代方案是
DeckView
拥有自己的@Query
,您只需将id
传递给其构造函数,然后它自己查询。这样,DeckView
正在使用的数据上触发的任何更改都将触发具有更新数据的新渲染。uyto3xhc2#
您缺少卡片的
Query
,但SwiftData当前不支持查询关系,即因此,您需要使用Core Data@FetchRequest
和 predicate 来表示关系。同时运行Core Data和Swift Data是相当复杂的,所以您可能只使用Core Data会更好,因为可能会缺少您需要的其他功能。