I have an issue while searching data from tableview. I want to search the data from tableview but stuck up while searching. Below is my code what i have tried. I'm getting issue is cannot assign value of type '[Employee]' to type '[String]' Please help. TIA
var empList: [Employee]!
var searchedText = [String]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchedText.count
} else {
return empList?.count ?? 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
if searching {
cell.lblTitle.text = searchedText[indexPath.row]
}else {
let resObjects = empList?[indexPath.row]
cell.lblTitle.text = resObjects?.emp_name
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchedText = empList.filter{$0.emp_name?.contains(searchText)}
// The above line gives me error as, cannot assign value of type '[Employee]' to type '[String]'
searching = true
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tableView.reloadData()
}
CodePudding user response:
Replace this:
searchedText = empList.filter{$0.emp_name?.contains(searchText)}
with this:
searchedText = empList.filter{$0.emp_name?.contains(searchText)}.map(\.emp_name) ?? []
The solution is mapping the array of Employee
to array of String
where the value is the emp_name
from Employee
model.
P.S: I'm using keyPaths >>> map(.emp_name) because it is shorter.
CodePudding user response:
As already mentioned in the comments it's highly recommended that the data source and the filtered array are of the same type.
And declare both as non-optional empty arrays and give them more meaningful names
var employees = [Employee]()
var filteredEmployees = [Employee]()
Then the data source methods become quite simple
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searching ? filteredEmployees.count : employees.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
let employee = searching : filteredEmployees[indexPath.row] : employees[indexPath.row]
cell.lblTitle.text = employee.emp_name
return cell
}
And in textDidChange
you have to consider that the user can delete all characters
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
searching = false
filteredEmployees.removeAll()
} else {
searching = true
filteredEmployees = employees.filter{$0.emp_name.range(of: searchText, options: .caseInsensitive) != nil}
}
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = ""
}