我正在尝试使用
SwiftData
存储此模型,以便在带有子树的 List
中显示它。
但是
List
要求其子级与父级具有相同的类型,这对于 SwiftData
来说似乎是一个问题。在构建并运行以下代码后,我立即在模型宏中收到“未知相关类型错误”致命错误。
型号:
@Model final class LibraryItem: Identifiable {
@Attribute(.unique) let id: UUID
var name: String
...
var subMenuItems: [LibraryItem]?
}
错误:
我使用一些递归函数构建树来反映给定 URL 的文件系统层次结构。这是我的
List
:
List(
libraryItems,
children: \.subMenuItems,
selection: Binding(
get: {
selectedLibraryItemId
},
set: { ids, _ in
selectionHandler(ids)
}
)
) { item in
Text(item.name)
}
这就是我初始化
ModelContainer
的方式:
init() {
let schema = Schema([LibraryItem.self])
let config = ModelConfiguration(schema: schema, groupContainer: .identifier("antonincharvat.com.appName"))
do {
let container = try ModelContainer(for: schema, configurations: config)
self.libraryItemsModelContainer = container
} catch {
fatalError("Couldn't create ModelContainer")
}
}
有什么办法可以做到这一点吗?我尝试使用计算属性作为子集合,但是
List
立即初始化其所有子集合,导致此方法无法使用。
正如我所见,您需要在模型中更改两件事才能使其工作,为关系的逆创建第二个属性,并使用
@Relationship
包装器作为关系属性之一来专门指出什么关键路径是关系的相反属性。
这就是我的
LibraryItem
模型最终的样子
@Model final class LibraryItem: Identifiable {
@Attribute(.unique) let id: UUID
var name: String
var subMenuItems: [LibraryItem]?
@Relationship(deleteRule: .nullify, inverse: \LibraryItem.subMenuItems)
var parentItem: LibraryItem?
init(name: String) {
self.id = UUID()
self.name = name
}
}