我正在嘗試列出最喜歡的報紙。在編輯模式下,串列顯示所有可用的報紙,用戶可以從中選擇他的最愛。選擇收藏夾后,串列僅顯示收藏夾。這是我的代碼:
struct Newspaper: Hashable {
let name: String
}
struct ContentView: View {
@State var editMode: EditMode = .inactive
@State private var selection = Set<Newspaper>()
var favorites: [Newspaper] {
selection.sorted(by: ({ $0.name < $1.name }))
}
let newspapers = [
Newspaper(name: "New York Times"),
Newspaper(name: "Washington Post")
]
var body: some View {
NavigationView {
List(editMode == .inactive ? favorites : newspapers, id: \.name, selection: $selection) { aliasItem in
Text(aliasItem.name)
}
.toolbar {
EditButton()
}
.environment(\.editMode, self.$editMode)
}
}
}
問題是串列進入編輯模式,但沒有出現選擇小部件。如果我Newspaper只用一個陣列替換String(并相應地修改其余代碼),那么選擇小部件確實會出現并且串列按預期作業。誰能解釋問題是什么?
我最初嘗試使用這樣的Identifiable報紙:
struct Newspaper: Codable, Identifiable, Equatable, Hashable {
var id: String { alias publicationName }
let alias: String
let publicationName: String
}
由于這不起作用,我測驗了上面更簡單的版本以試圖查明問題。
由于我需要保存收藏夾,因此報紙必須是可編碼的,因此不能使用 UUID,因為它們是從磁盤讀取的,并且完整的報紙陣列是從服務器獲取的。這就是為什么我將其id作為計算屬性。
Yrb:s answer提供了問題的解決方案:選擇 Set 的型別必須與id您在Identifiable結構中使用的型別相同,而不是您在List.
因此,在我的情況下(使用Identifiable報紙版本),選擇 Set 必須是 typeSet<String>而不是Set<Newspaper>因為idNewspaper 是String.
uj5u.com熱心網友回復:
您的問題源于List's選擇模式使用該id:屬性來跟蹤您的選擇。由于您要宣告Listas List(..., id: \.name, ...),因此您的selectionvar 必須是 type String。如果您將其更改為List(..., id: \.self, ...),它會起作用,但是在這樣的串列中使用 self 會帶來它自己的問題。為了與最佳實踐保持一致,暫時忘記選擇,您應該使用Identifiable結構。然后應該通過結構上的引數來List識別元素。id(我使用了一個 UUID)
處理選擇,這意味著您需要將其定義為@State private var selection = Set<UUID>().剩下的就是處理你的favorites計算變數。無需回傳您的陣列selection,您只需過濾newspapers陣列中包含的那些元素selection。最后,剩下的就是:
struct Newspaper: Identifiable, Comparable {
let id = UUID()
let name: String
static func < (lhs: Newspaper, rhs: Newspaper) -> Bool {
lhs.name < rhs.name
}
}
struct ContentView: View {
@State var editMode: EditMode = .inactive
@State private var selection = Set<UUID>()
var favorites: [Newspaper] {
newspapers.filter { selection.contains($0.id) }
}
let newspapers = [
Newspaper(name: "New York Times"),
Newspaper(name: "Washington Post")
]
var body: some View {
NavigationView {
VStack {
List(editMode == .inactive ? favorites.sorted() : newspapers, selection: $selection) { aliasItem in
Text(aliasItem.name)
}
.toolbar {
EditButton()
}
.environment(\.editMode, self.$editMode)
Text(selection.count.description)
}
}
}
}
編輯:
在您的評論中,您說Newspaper需要“可編碼”,并暗示id服務器回應中沒有引數。下面Newspaper是Codable,但不會期望id在服務器回應中,而是會簡單地添加自己的常量id。有一個計算的id.id永遠不應該改變,它應該是獨一無二的。UUID給你。
struct Newspaper: Identifiable, Comparable, Codable {
let id = UUID()
let name: String
enum CodingKeys:String,CodingKey {
case name
}
static func < (lhs: Newspaper, rhs: Newspaper) -> Bool {
lhs.name < rhs.name
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/413371.html
標籤:
