1

I have tableview controller with searchBar and I want to search in items inside array in my example i want to search for teamsArr items inside leagues Array

now my code search fine in Legue Name not in Teams name

my code:

import UIKit

struct Legue {
var name:String
var num:Int
var teamsArr:[String]
}

class Table1ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdating {

@IBOutlet var myTable: UITableView!

let cellID="MyCellID"
var Legues:[Legue]=[]
var searchController=UISearchController(searchResultsController: nil)
var filterLegues:[Legue]=[]





func filterContentForSearch(searchText:String,scope:String="All2")
{
    filterLegues=Legues.filter{leg in
        return leg.name.containsString(searchText) **\\ Here search only in Legue name ,but i want to search in teams name**
     }


    myTable.reloadData()
}
override func viewDidLoad() {
    super.viewDidLoad()

    myTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellID)

    myTable.delegate=self
    myTable.dataSource=self
    Legues=self.loadData()

    searchController.searchResultsUpdater=self

    searchController.dimsBackgroundDuringPresentation=false
    definesPresentationContext=true
    myTable.tableHeaderView=searchController.searchBar
    searchController.hidesNavigationBarDuringPresentation=false


}




func loadData()->[Legue]
{
    let arrlegue=[Legue(name:"Spain",num: 3,teamsArr: ["Barcelona","Atletico Madrid","Real Madrid"]),Legue(name:"Saudi",num: 4,teamsArr: ["Ahli","Hilal","AlNaser","AlEtihad"]),Legue(name:"England",num: 2,teamsArr:["Lestercity","Man City"]),Legue(name:"Italy",num: 5,teamsArr: ["Juventus","Napoli","AS Roma","Internazionale","AC Milano"])]

    return arrlegue
}

override func prefersStatusBarHidden() -> Bool {
    return true
}

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

    if searchController.active && searchController.searchBar.text != ""
   {
    let x=filterLegues[section].teamsArr.count
    return x
    }

    let x=Legues[section].teamsArr.count
    return x
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    if searchController.active && searchController.searchBar.text != ""
    {
    return filterLegues.count
    }
    else
    {
        return Legues.count
    }
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if searchController.active && searchController.searchBar.text != ""
    {
    return filterLegues[section].name
    }
    else
    {
        return Legues[section].name
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell=myTable.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath)
    if searchController.active && searchController.searchBar.text != ""
    {
  cell.textLabel?.text="\(filterLegues[indexPath.section].teamsArr[indexPath.row])"
        cell.imageView?.image=UIImage(named: filterLegues[indexPath.section].name)
    }
    else
    {
    cell.textLabel?.text="\(Legues[indexPath.section].teamsArr[indexPath.row])"
    cell.imageView?.image=UIImage(named: Legues[indexPath.section].name)
    }
        return cell
}

func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {

    if sourceIndexPath != destinationIndexPath
    {
    let itemToMove=Legues[sourceIndexPath.section]
    Legues.removeAtIndex(sourceIndexPath.section)
    Legues.insert(itemToMove, atIndex: destinationIndexPath.section)

    myTable.reloadData()
    }
    }

@IBAction func editButton(sender: UIBarButtonItem) {

  myTable.editing=true
}

func updateSearchResultsForSearchController(searchController: UISearchController)
{
    filterContentForSearch(searchController.searchBar.text!)


}

}

3 Answers 3

1

my code is like that and it works:

//
//  InterestsTableViewController.swift
//  OyventIOSApp
//
//  Created by Mehmet Sen on 9/9/16.
//  Copyright © 2016 Mehmet Sen. All rights reserved.
//

import UIKit

class InterestsTableViewController: UITableViewController {

    let api: InterestAPI = InterestAPI()
    var pkUserID : Double!
    var ismyprofile : Bool! = false
    var sections: [SectionData] = []
    let searchController = UISearchController(searchResultsController: nil)
    var filteredSections: [SectionData] = []


    func filterContentForSearchText(searchText: String, scope: String = "ALL") {

        filteredSections = sections.map{ (section) -> SectionData in
            let interests = section.interests.filter{$0.name!.localizedCaseInsensitiveContainsString(searchText.lowercaseString)}
            return SectionData(title: section.title, interests: interests)}.filter{$0.numberOfItems > 0
        }
        tableView.reloadData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        pkUserID =  NSNumberFormatter().numberFromString(NSUserDefaults.standardUserDefaults().stringForKey("blabla_id")!)?.doubleValue

        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        tableView.tableHeaderView = searchController.searchBar

        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
        api.fetchUserInterestList(pkUserID) { (results: NSDictionary) in

            var resultsArr: [Interest] = results["results"] as! [Interest]
            dispatch_async(dispatch_get_main_queue(), {

                resultsArr = Interest.interestsWithJSON(resultsArr)
                for i in 0 ..< resultsArr.count {

                    var exists: Bool = false

                    for j in 0 ..< self.sections.count {
                        if self.sections[j].title == resultsArr[i].scope{
                            exists = true
                            self.sections[j].interests.append(resultsArr[i])
                        }
                    }

                    if(exists == false){
                        let sectionData = SectionData(title: resultsArr[i].scope!, interest: resultsArr[i])
                        self.sections.append(sectionData)
                    }


                }

                self.tableView!.reloadData()
                UIApplication.sharedApplication().networkActivityIndicatorVisible = false
            })
        }

    }


    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return searchController.active && searchController.searchBar.text != "" ? filteredSections.count : sections.count
    }

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

        return searchController.active && searchController.searchBar.text != "" ? filteredSections[section].numberOfItems  : sections[section].numberOfItems
    }


    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sections[section].title
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
        cell.backgroundColor = UIColor.clearColor()

        let interest:Interest
        interest = searchController.active && searchController.searchBar.text != "" ? filteredSections[indexPath.section][indexPath.row] : sections[indexPath.section][indexPath.row]

        // insert the special characters using edit > emoji on the menu
        cell.textLabel?.textColor = UIColor.whiteColor()
        cell.textLabel!.text = interest.checked  ? "✅ " + interest.name! : interest.name!

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        //get the interest object
        let interest:Interest = sections[indexPath.section][indexPath.row]

        if(self.ismyprofile != false){
            interest.toggleCheck()

            //add user interest
            if(interest.checked){

                api.addUserInterest(pkUserID, interestid: interest.interestid!, completionHandler: { (result: NSDictionary) in

                    let resultValue: Bool = result["success"] as! Bool!
                    if(resultValue){
                        //self.interests[indexPath.row] = interest
                        self.sections[indexPath.section][indexPath.row] = interest
                    }else{
                        interest.toggleCheck() //reverse back
                    }
                })
            }else{//delete user interest

                api.deleteUserInterest(pkUserID, interestid: interest.interestid!, completionHandler: { (result: NSDictionary) in

                    let resultValue: Bool = result["success"] as! Bool!
                    if(resultValue){
                        //self.interests[indexPath.row] = interest
                        self.sections[indexPath.section][indexPath.row] = interest
                    }else{
                        interest.toggleCheck() //reverse back
                    }
                })
            }
        }

        tableView.reloadData()
    }



    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}


class SectionData {
    var title: String
    var interests : [Interest] = []

    init(title: String, interest: Interest) {
        self.title = title
        self.interests.append(interest)
    }

    init(title: String, interests: [Interest]) {
        self.title = title
        self.interests = interests
    }

    var numberOfItems: Int {
        return interests.count
    }

    subscript(index: Int) -> Interest {

        get {
            return interests[index]
        }
        set(newValue) {
            interests[index] = newValue
        }

    }
}


extension InterestsTableViewController: UISearchResultsUpdating {
    func updateSearchResultsForSearchController(searchController: UISearchController) {
        filterContentForSearchText(searchController.searchBar.text!)
    }
}


//
//  Interest.swift
//  OyventIOSApp
//
//  Created by Mehmet Sen on 8/11/16.
//  Copyright © 2016 Mehmet Sen. All rights reserved.
//

import Foundation

class Interest {

    var interestid: Int?
    var name: String?
    var userid: Double?
    var scope: String?
    var checked: Bool = false

    init(interestid: Int, name: String, userid: Double, scope: String, checked: Bool){

        self.interestid = interestid
        self.name = name
        self.userid = userid
        self.scope = scope
        self.checked = checked
    }

    class func interestsWithJSON(allResults: NSArray) -> [Interest] {

        var interests = [Interest]()

        if allResults.count > 0 {

            for result in allResults {

                let interestid = result["pkinterestid"] as? Int
                let name = result["name"] as? String
                let userid = result["fkuserid"] as? Double
                let scope = result["scope"] as? String
                let checked: Bool = userid > 0 ? true : false

                //print("interestid: \(interestid!) name: \(name!) userid: \(userid!)  checked: \(checked)")

                let newInterest = Interest(interestid: interestid!, name: name!, userid: userid!, scope: scope!, checked: checked)
                interests.append(newInterest)
            }
        }

        return interests;
    }

    internal func toggleCheck(){
        self.checked =  !self.checked
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Your filter is right, but you're not binding the table view delegate properly. You have to use filtered the array as datasource of the table view on cellForRowAtIndexPath.

func filterContentForSearch(searchText:String,scope:String="All")
{
    filterLegues = Legues.filter{leg in return leg.name.containsString(searchText) || leg.teamsArr.filter{$0.containsString(searchText)}.count > 0 }
}

And this way you can search in both name and teams

3 Comments

it is working fine with me but i can search for "Spain,Saudi,England,Italy" only , but i want to search for teams name , i will update my question to see full code
Just updated my answer. That's how you can search on the teams Array.
Thanks , but when i search for "Man City" retrive whole section and output like this: [MY_Test_App.Legue(name: "England", num: 2, teamsArr: ["Lestercity", "Man City"])] , i want only to see "Man City" not all teams in section
0

This should do the trick

Flatten the league's teamArray and filter

func filterContentForSearch(searchText:String,scope:String="All")
{
    filterLegues = arrlegue.filter{$0.teamsArr.contains{$0.localizedCaseInsensitiveContainsString("Juv")}}

    myTable.reloadData()
}

4 Comments

Error: Cannot assign value of type '[String]' to type '[Legue]'
but when i search for "Man City" retrive whole section and output like this: [MY_Test_App.Legue(name: "England", num: 2, teamsArr: ["Lestercity", "Man City"])] , i want only to see "Man City" not all teams in section
You'll have to map then filter something like this: let searchResult = arrlegue.map { (legue) -> Legue in let newLeague = legue.teamsArr.filter{$0.localizedCaseInsensitiveContainsString("B")} return Legue(name: legue.name, num: newLeague.count, teamsArr: newLeague) }.filter{$0.num > 0 }
@cjay I do the same thing for my project but it gives syntax error before "return" : filteredSections = sections.map{ (section) -> SectionData in let newSection = section.interests.filter{$0.name!.localizedCaseInsensitiveContainsString(searchText.lowercaseString)} return SectionData(title: newSection.title, interest: newSection.interests)}.filter{$0.numberOfItems > 0 }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.