I've got a struct Array that I'm using to populate my tableview. But I am unable to get my searchBar to work correctly. My original searchBar code was created when I was using a more "basic" array. After converting to struct it no longer works. I am getting 3 errors from Xcode. I've identified the errors in the code with // <-- ERROR. Thanks for your help!
import UIKit
struct Material {
var name : String
var lbft : String
var gcm : String
}
class ViewController: UIViewController {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet var tableView: UITableView!
let materialData = [
Material(name: "Acetaminohen Powder, Unmilled", lbft: "43", gcm: "0.688794"),
Material(name: "Acetylene Black, 100% Compressed", lbft: "35", gcm: "0.560646"),
Material(name: "Acetylsalicyic Acid", lbft: "20", gcm: "0.320369"),
Material(name: "Acrylamide", lbft: "34", gcm: "0.54463"),
Material(name: "Acrylic Granules, Coarse", lbft: "40", gcm: "0.64"),
Material(name: "Acrylic Granules, Fine", lbft: "36", gcm: "0.58"),
Material(name: "Acrylonitrile Butadien Styrene (Abs) Resin", lbft: "50", gcm: "0.8"),
Material(name: "Acrylonitrile Butadiene Styrene (Abs) Granules", lbft: "36", gcm: "0.58"),
Material(name: "Activated Alumina", lbft: "42.5", gcm: "0.68"),
Material(name: "Activated Carbon", lbft: "32.5", gcm: "0.52"),
Material(name: "Actylene Black", lbft: "45.5", gcm: "0.73"),
Material(name: "Aero Xanthates", lbft: "112.5", gcm: "1.8"),
Material(name: "Aerolyte", lbft: "51", gcm: "0.82"),
Material(name: "Aerosil, Fumed Silica", lbft: "32", gcm: "0.51"),
Material(name: "Aerosil, Silicon Dioxide", lbft: "30", gcm: "0.48"),
Material(name: "Alaluren", lbft: "112", gcm: "1.79")]
var searchMaterial = [String]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchMaterial.count
} else {
return materialData.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.numberOfLines = 0
if searching {
cell.textLabel?.text = searchMaterial[indexPath.row]
} else {
cell.textLabel?.text = materialData[indexPath.row] // <-- ERROR Cannot assign value of type 'Material' to type 'String'
}
return cell
}
}
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.setShowsCancelButton(true, animated: true)
searchMaterial = materialData.filter({$0.prefix(searchText.count) == searchText}) // <-- ERROR Cannot assign value of type '[Material]' to type '[String]'
// <-- ERROR Value of type 'Material' has no member 'prefix'
searching = true
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searching = false
searchBar.text = ""
tableView.reloadData()
}
}
Hi Sean I believe I have solved this,
Everything in your tableView delegate functions are correct
Make sure to create this var at top level
var searchMaterial = [Material]()
Then add this to your searchBar function:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
guard !searchText.isEmpty else {
searchMaterial = materialData
tableView.reloadData()
return // When no items are typed, load your array still
}
searchMaterial = materialData.filter({ (Material) -> Bool in
Material.title.lowercased().contains(searchText.lowercased())
})
searchBar.setShowsCancelButton(true, animated: true)
searching = true
tableView.reloadData()
Hope this helped!!!