ggnoredo
ggnoredo

Reputation: 821

Swift SearchBar Filtering & Updating Multiple Arrays

I need to implement a searchBar that searches & filters a tableview with 2 labels. Label data coming from 2 different arrays. So when i filter through array 1/label 1 it filters but label 2 remains same so results are mixed. Both arrays are created after SQL Query results with 2 columns of data. I mean arr1[0] and arr2[0] are the same row but different columns. I'm stuck after too many tries. Here's the latest code:

var arr1 = [String]()
var arr2 = [String]()
var filtered:[String] = []

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if(searchActive) {
        return filtered.count
    } else {
        return arr1.count
    }
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> xxTableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "xxCell", for: indexPath) as! xxTableViewCell

    if(searchActive){

        cell.label1.text = filtered[(indexPath as NSIndexPath).row]

    } else {

        cell.label1.text = arr1[(indexPath as NSIndexPath).row]
        cell.label2.text = arr2[(indexPath as NSIndexPath).row]

    }
    return cell
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    filtered = arr1.filter({ (text) -> Bool in
        let tmp: NSString = text as NSString
        let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)
        return range.location != NSNotFound
    })
    if(filtered.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }


    self.tableView.reloadData()
}

Upvotes: 0

Views: 1237

Answers (2)

dahiya_boy
dahiya_boy

Reputation: 9503

Issue : When searchActive = true, you have no value for label2.text in cellForRow. So Whenever you reload the tableView after the filter is just update new values for label1.

Solution :

Modify your code like this.

if(searchActive){

    cell.label1.text = filtered[(indexPath as NSIndexPath).row]
    cell.label2.text = @"" //assign value to label2 after filter 
} else {

    cell.label1.text = arr1[(indexPath as NSIndexPath).row]
    cell.label2.text = arr2[(indexPath as NSIndexPath).row]

}

Upvotes: 1

Russell
Russell

Reputation: 5554

If arr1[] and arr2[] are two columns of a single row of data, then you should have a single array. There are many ways of doing this - tuples, classes, structs - but I tend to go for a struct. If you have additional processing that you will want to perform it could be better implemented as a class, but the same principle applies.

Define the struct you need

struct MyDataStruct
{
    var label1 : String = ""
    var label2 : String = ""
}

Then define an array of this type (instead of arr1, arr2)

var myData = [MyDataStruct]()

Then build up the data and search array just as you were before - but into this single structure

myData.append(MyDataStruct(label1: "Hello", label2: "World"))

Final step is in the tableView methods

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> xxTableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "xxCell", for: indexPath) as! xxTableViewCell

    if(searchActive){
        cell.label1.text = filtered[indexPath.row].label1
    } else {
        cell.label1.text = myData[indexPath.row].label1
        cell.label2.text = myData[indexPath.row].label2 
    }
    return cell
}

Upvotes: 2

Related Questions