Я пытаюсь использовать панель поиска для поиска / фильтрации через двухуровневую модель данных в SwiftUI:
struct CategorySection: Identifiable {
var id = UUID()
var title: String
var image: String
var color: Color
var paintings: [Painting]
}
struct Painting {
var title: String
var size: String
var year: String
var text: String
var show: Bool
}
let categorySectionData: [CategorySection] = [
CategorySection(title: "Flowers",
image: "Spring",
color: Color(#colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1)),
paintings: [
Painting(title: "Spring", size: "70 x 60cm", year: "2001", text: "Spring", show: false),
Painting(title: "Flowers", size: "60 x 50cm", year: "2002", text: "The", show: false),
Painting(title: "Corn Poppys", size: "70 x 50cm", year: "2005", text: "Year", show: false),
]
),
CategorySection(title: "Animals",
image: "Deers",
color: Color(#colorLiteral(red: 0.2745098174, green: 0.4862745106, blue: 0.1411764771, alpha: 1)),
paintings: [
Painting(title: "Tigers", size: "70 x 60cm", year: "2001", text: "Spring", show: false),
Painting(title: "Deers", size: "60 x 50cm", year: "2002", text: "The", show: false),
Painting(title: "Puppies", size: "70 x 50cm", year: "2005", text: "Year", show: false),
]
)
]
Основная цель - фильтровать элементы, такие как title: "Spring"
и * 1005. * в Painting
структуре внутри CategorySection
, отобразите совпавшие результаты в виде рисунков title
с в списке и передайте данные через NavigationLink
для следующего просмотра SearchDetail
, чтобы отобразить, когда пользователь нажимает на один из них.
Я попытался выполнить следующие действия для поиска первых элементов, но Xcode только что выдал мне кучу ошибок.
let array = locationSectionData[0].paintings[0]
List {
ForEach(array.filter {$0.hasPrefix(searchText) || searchText == ""}, id:\.self) { searchText in
NavigationLink(destination: SearchDetail(item: searchText)) {
Text(searchText)
}
}
}
Однако вышеприведенное решение работает для простых массивов, таких как:
let array = ["Spring", "Deer", "New Year", "Flowers"]
, но не для многоуровневых структур данных.
В идеале, результат поиска должен возвращать целые экземпляры структуры Painting
, такие как
Painting(title: "Spring", size: "70 x 60cm", year: "2001", text: "Spring", show: false)
, а не только отдельные элементы, которые соответствуют, если какой-либо элемент внутри него соответствует входу панели поиска ,
Если у кого-то есть идеи, как я могу решить эту проблему, это было бы здорово! На данный момент, я даже не уверен, что это возможно, учитывая текущую структуру данных. Модификации структуры данных являются приемлемыми.
Спасибо!
Отредактировано: Мне удалось отобразить полный список названий картин без функции фильтра, благодаря помощи @ jtouzy
List {
ForEach(categorySectionData) { section in
Section(header: Text(section.title)) {
ForEach(section.paintings.indices, id: \.self) { painting in
ForEach(section.paintings[painting].title.filter {$0.contains(searchText) || searchText.isEmpty}, id:\.self) { searchText in
NavigationLink(destination: SearchDetail(painting: section.paintings[painting])) {
Text(section.paintings[painting].title)
}
}
}
}
}
}
Однако Xcode сообщает об ошибке Value of type 'String.Element' (aka 'Character') has no member 'contains'
в строке ForEach(section.paintings[painting].title.filter {$0.contains(searchText) || searchText.isEmpty}, id:\.self) { searchText in
. Я знаю, что это, вероятно, потому что теперь это не массив.