Я пытаюсь создать список из массива, содержащего типы, соответствующие протоколу. Я могу отображать и понижать типы в .onAppear, но не могу использовать массив в качестве источника для списка и выполнять понижающее преобразование для создания текстовых представлений.
Сообщение компилятора
«Тип «любой IRow» не может соответствовать «Идентифицируемому»»
Если я использую идентификатор вот так
Список(item.rows, id: .self)
сообщение компилятора о
«не может соответствовать «Hashable»
protocol IRow: Identifiable, Hashable {
var id: UUID { get }
var rowType: String { get }
}
struct TextItemRow: IRow {
let id = UUID()
let rowType = "text"
var text: String = ""
}
struct HeadlineItemRow: IRow {
let id = UUID()
let rowType = "headline"
var text: String = ""
}
struct Item: Identifiable {
let id = UUID()
var rows: [any IRow] = [HeadlineItemRow(text: "H_mock"), TextItemRow(text: "T_mock")]
}
struct ContentView: View {
let item = Item()
var body: some View {
VStack {
List(item.rows) { row in
}
}
.onAppear {
var _ = item.rows.map() {
if let r = $0 as? HeadlineItemRow {
print("\(r.id.uuidString) : \(r.text)")
} else if let r = $0 as? TextItemRow {
print("\(r.id.uuidString) : \(r.text)")
}
}
}
}
}
Спасибо, что нашли время. И да, это прекрасно отвечает на мой вопрос. Отсутствовала только часть идентификатора.
Если можно, один вопрос. В чем именно разница между моим решением «id: \.self» и «id: \.id».
Хороший вопрос, я обычно избегаю соответствия Identifying, если не может быть предоставлен значимый идентификатор, выбирая id: .self в SwiftUI для ясности. Использование self в качестве идентификатора напрямую может привести к проблемам с производительностью, таким как метод линейного хеширования и невозможность анимировать изменения.
Пытаться
List(item.rows, id: \.id) { row in
Text(row.rowType)
}
у меня работает.
Почему отрицательный голос? Это разумное решение проблемы ОП (проголосовали).
Эй, этот ответ может быть очень полезным. Посмотрите: forums.swift.org/t/how-to-conform-protocol-to-identifying/…