I have 2 arrays. The 1st, "data", is filled with text that goes in a tableview. The 2nd, "identities", is filled with storyboard ids. Both array indexes match to one another, as in if the user chooses the 1st item in the data array, then they will segue to the 1st storyboard id in the identities array.
The problem is, when the 1st array is sorted, the second array stays the same. So the storyboard id no longer matches the cell of the tableview.
I would like to somehow either align the indexes, so that they both react to the filter in the same way, or possibly change the 2 arrays into 1. But the way I segue needs to stay close to the same.
Here is the code:
@IBOutlet weak var toolTable: UITableView!
@IBOutlet weak var searchForTool: UISearchBar!
var searchActive : Bool = false
var filtered : [String] = []
var data = [" Data1", " Data2"]
var identities = ["A", "B"]
override func viewDidLoad() {
super.viewDidLoad()
toolTable.delegate = self
toolTable.dataSource = self
searchForTool.delegate = self
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchActive = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filtered = data.filter { text in
return text.lowercased().contains(searchText.lowercased())
}
if(filtered.count == 0){
searchActive = false
} else {
searchActive = true
}
self.toolTable.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
}
return data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
if(searchActive){
cell.toolLabel.text = filtered[indexPath.row]
} else {
cell.toolLabel.text = data[indexPath.row]
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vcName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
self.navigationController?.pushViewController(viewController!, animated: true)
}
}Any help would be greatly appreciated.
change the 2 arrays into 1
This seems to be the preferred way.
//...
//### change the 2 arrays into 1
typealias Item = (data: String, identity: String)
// var filtered : [String] = []
// var data = [" Data1", " Data2"]
// var identities = ["A", "B"]
var filtered: [Item] = []
var items: [Item] = [
(data: " Data1", identity: "A"),
(data: " Data2", identity: "B")
]
//...
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filtered = items.filter { item in
item.data.localizedCaseInsensitiveContains(searchText)
}
searchActive = !filtered.isEmpty
self.toolTable.reloadData()
}
//...
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchActive {
return filtered.count
}
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
if searchActive {
cell.toolLabel.text = filtered[indexPath.row].data
} else {
cell.toolLabel.text = items[indexPath.row].data
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vcName = items[indexPath.row].identity
let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
self.navigationController?.pushViewController(viewController!, animated: true)
}This is a simplified example, so the type `Item` is a tuple type. You can make it to a struct or a class.
Not too far from your original code, I believe.