McDonal_11
McDonal_11

Reputation: 4075

How to filter multiple fields in UITableView in swift

I am having country codes and country names in String Array. I just filtered country names and displaying in the filtered tableView. But, while displaying, I unable to fetch the respective country code from original tableview. Country code not getting filtered. Kindly help me. How to filter multiple fields in tableView cell.

My Code:

var countries = [String]()
for countryCodes : AnyObject in NSLocale.ISOCountryCodes() {
    let dictionary : NSDictionary = NSDictionary(object:countryCodes, forKey:NSLocaleCountryCode)
    let identifier : NSString? = NSLocale.localeIdentifierFromComponents(dictionary)
    if ((identifier) != nil) {
        let country : NSString = NSLocale.currentLocale().displayNameForKey(NSLocaleIdentifier, value: identifier!)!
        countries.append(country)
        println(countries)
    }
}
println(countries)
var country_codes = [String]()
country_codes =  NSLocale.ISOCountryCodes() as [String]
println(country_codes) //Working Successfully.

//SEARCH BAR WHILE TYPING TEXT
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {

        if(countElements(searchBar.text) >= 3)
        {
            searchActive = true

            filtered = countries.filter({ (text) -> Bool in
                let tmp: NSString = text
                let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
                return range.location != NSNotFound
            })
//I filtered only one fields. So, Filtered results are working fine, but, I am having one more fields in tableview cell. That is displaying different datas. I dont know how to filtered multiple fields.
            if(filtered.count == 0 || countElements(searchBar.text) == 0)
            {
                searchActive = false
                self.countryTableView.reloadData()
            }
            else
            {
                searchActive = true
                self.countryTableView.reloadData()
            }

        }
        else
        {

            searchActive = false
            self.countryTableView.reloadData()
        }

    }

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = countryTableView.dequeueReusableCellWithIdentifier("country", forIndexPath: indexPath) as country_tblCell

        //println("Cell for ROws \(searchActive)")
        if(searchActive)
        {
            if(filtered.count == 0 || countElements(searchBar.text) == 0)
            {
                searchActive = false
                self.countryTableView.reloadData()
            }

            else
            {
                println("First Index \(indexPath.row)")
                cell.country_Label.text = filtered[indexPath.row]
                cell.countryCodeLabel.text = countryCodes[indexPath.row] //Here need to display filtered datas for Country code.
                println("Second Index \(indexPath.row)")
            }
        }
        else
        {
            println("Normal First Index \(indexPath.row)")
            cell.selectionStyle = .None
            cell.country_Label.text = countries[indexPath.row]
            cell.countryCodeLabel.text = countryCodes[indexPath.row]
            cell.layer.borderColor = validateBorderColor.CGColor
            cell.layer.borderWidth = 1
            println("Normal Second Index \(indexPath.row)")
        }

        return cell
    }

My Output

enter image description here

Upvotes: 3

Views: 4340

Answers (3)

Ronak
Ronak

Reputation: 147

Above answer in Swift 3.0

var countryAndCode: [(country:String , code: String)] = []
for i in 0...coutries.count-1 {
  countryAndCode += [(country:countries[i] , code:country_codes[i])]
}

Then perform the filtering on this tuple:

filtered = countryAndCode.filter({ (data) -> Bool in
     let tmp: NSString = data.country // the name from the variable decleration
     let range = tmp.range(of: searchText, options: .caseInsensitive)
     return range.location != NSNotFound
})

Upvotes: 0

Desistreus
Desistreus

Reputation: 361

I had a similar problem earlier. First step is the same I guess. create a tuple where the country and code are in one object together.

var countryAndCode: [(country:String , code: String)] = []

Then I basically used an OR operator for the fields. Your code:

        filtered = countries.filter({ (text) -> Bool in
            let tmp: NSString = text.attribute
            let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            return range.location != NSNotFound
        })

Into something like this:

        filtered = countries.filter({ (text) -> Bool in
            let tmp: NSString = text.attribute
            let range = tmp.country.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch) || tmp.code.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            return range.location != NSNotFound
        })

And in your case you could do && if you want to filter on both fields.

Upvotes: 0

Raja Vikram
Raja Vikram

Reputation: 1980

Try using tuples.

This is a great feature in swift.

After getting countries and country_codes

Add them to this tuple

var countryAndCode: [(country:String , code: String)] = []
for i in 0...coutries.count {
  countryAndCode.append(country:countries[i] , code:country_codes[i])//this shows error in XCode some times
    //if the above code doesn't compile then use the below code
  countryAndCode += [(country:countries[i] , code:country_codes[i])]
}

Then perform the filtering on this tuple:

filtered = countryAndCode.filter({ (data) -> Bool in
        let tmp: NSString = data.country // the name from the variable decleration
            let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            return range.location != NSNotFound
        })

Finally in the cellForRowAtIndexPath method use this tuple

cell.country_Label.text = filtered[indexPath.row].country
cell.countryCodeLabel.text = filtered[indexPath.row].code

For more information on tuples you can visit http://www.raywenderlich.com/75289/swift-tutorial-part-3-tuples-protocols-delegates-table-views

Upvotes: 3

Related Questions