Home > Software engineering >  How to make search/filtered result on the top of Tableview?
How to make search/filtered result on the top of Tableview?

Time:12-04

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()
            
        }
    }

enter image description here

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)
}
  • Related