I am trying to add a UISearchBar to a UITableviewController that gets data from a db call. I added uisearchbar above the tableview in storyboard and made the outlet added delegate in class declaration and viewdidload. Code seems right but I am getting no reaction when typing in the searchClients function. Not sure what I am missing. No errors showing in console.
import UIKit
class TableViewController: UITableViewController, UISearchBarDelegate {
var CompanyID = ""
var CompanyName = ""
var ClientList = [Client]()
var filteredArray = [Client]()
let URL_SERVICE = "https://fetch.php"
@IBOutlet var searchClients: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchClients.delegate = self
filteredArray = ClientList
// omitted call to get data, as it loads fine initially
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Client", for: indexPath)
let client = filteredArray[indexPath.row]
let title = client.Name
cell.textLabel?.text = title
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.CompanyID = filteredArray[indexPath.row].CompanyID
self.CompanyName = filteredArray[indexPath.row].Name
}
func searchClients(_ searchBar: UISearchBar, textDidChange searchText: String) {
//let text: String = self.searchClients.text ?? ""
print("search for \(searchText)")
self.filteredArray = []
if (searchText == "") {
self.filteredArray = self.ClientList
} else {
for item in self.ClientList {
if (item.Name.lowercased().contains(searchText.lowercased())) {
self.filteredArray.append(item)
}
}
}
print(filteredArray)
self.tableView.reloadData()
}
}
What am I missing here that keeps searchBar function from firing?
CodePudding user response:
You are not implementing any method from the UISearchBarDelegate
since your searchClients
function is not correctly named. You will need to rename it to searchBar
to actually implement the function from the delegate protocol.
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
Few Nitpicks
- In Swift we are naming properties by starting with a lowercase letter
var companyID = ""
var companyName = ""
var clientList = [Client]()
var filteredArray = [Client]()
let urlService = "https://fetch.php"
- You can skip every
self.
you are adding as a prefix when referencing to a property or function within the scope of the declaring type.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
companyID = filteredArray[indexPath.row].companyID
companyName = filteredArray[indexPath.row].name
}
- Its much cleaner when protocol conformances are implemented using extensions so the code is nicely separated and they do not mix with each other.
extension TableViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
//let text: String = self.searchClients.text ?? ""
print("search for \(searchText)")
filteredArray = []
if searchText == "" {
filteredArray = clientList
} else {
filteredArray = clientList.filter { item in
item.name.lowercased().contains(searchText.lowercased())
}
}
print(filteredArray)
tableView.reloadData()
}
}