I am making an information app, it has sections and rows on the table view. There is a searchBar on the top of tableView to filter the name but When i search name, the corresponding name shows as per the array but I want the search result should be on top of the tableView.
I have used some filter in searchbar delegate textDidChange but it is not working what I expect it to be.
For Example: I am searching for "kumar", it is on the 3rd row as per our data. but i want it to be on the top of the table.
Reason to solve the issue: If there are lots of rows in the section and if there is a name starts with "Z". It goes all the way down to the tableView
I am very new to swift, Xcode, UIKit.
Model:
struct Datas {
var sectionName: String
var shops: [Detail1]
}
struct Detail1 {
var name: String
var contact: [String]
var address: [String]
}
Data:
var data1 = [
Datas(sectionName: "A", shops: [
Detail1(name: "raj", contact: ["454545" ], address: ["KNR" ]),
Detail1(name: "bala", contact: ["878787"], address: ["NGI"]),
Detail1(name: "raja", contact: ["212121"], address: ["CHN"])
]),
Datas(sectionName: "B", shops: [
Detail1(name: "balaji", contact: ["9898898"], address: ["KNR"]),
Detail1(name: "Siva", contact: ["787878"], address: ["LKD"]),
Detail1(name: "Kumar", contact: ["2323232"], address: ["MNR"])
])
]
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = []
if searchText == "" {
filteredData = data1
tableView.reloadData()
DispatchQueue.main.async {
searchBar.resignFirstResponder()
}
} else {
for word in data1 {
if word.shops.contains(where: {$0.name.lowercased().prefix(searchText.count) == searchText.lowercased()}) ||
word.sectionName.lowercased().prefix(searchText.count) == searchText.lowercased()
{
filteredData.append(word)
}
}
tableView.reloadData()
}
}
CodePudding user response:
I think your problem lies in the fact that you are only filtering sections while you should also filter the items:
filteredData = data1.compactMap { section in
if section.sectionName.lowercased().hasPrefix(searchText.lowercased()) {
// return whole section
return section
}
let filteredShops = section.shops.filter { $0.name.lowercased().hasPrefix(searchText.lowercased()) }
guard !filteredShops.isEmpty {
// no match in the given section
return nil
}
// return an updated section with filtered shops
return Datas(sectionName: section.sectionName, shops: filteredShops)
}