search bar in ios swift

Angad Singh picture Angad Singh · May 3, 2017 · Viewed 24.5k times · Source

I want to use search bar in my app.I am trying to use it but exceptions are coming . I have got an array of dictionary called member [[String:Anyobject]] and from this i have taken out the name and stored into an array data of type string and it is not working.

Here is my code :

import UIKit

class hcbaViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate {

@IBOutlet var searchbar: UISearchBar!

@IBOutlet var tableview: UITableView!

var member = [[String:AnyObject]]()

var members = [String:AnyObject]()

var searchActive = true
var filtered:[String] = []
var data: [String] = []


override func viewDidLoad() {
    super.viewDidLoad()
    print(data)
    print("________-----------________----------")
 print(member)


    // Do any additional setup after loading the view.
}

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) -> 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()
}

 func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    return "MemberDirectory"

}

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

    return member.count

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

   // return member.count

}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)

     var display = member[indexPath.row]

    cell.textLabel?.text = display["Name"] as! String?
    cell.detailTextLabel?.text = display["email"] as? String


    let n = display["Name"] as! String
     data.append(n)

    return cell
}


  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let vc = segue.destination as! hcbadetailViewController
        vc.kk = members

}


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

       members = member[indexPath.row]
       self.performSegue(withIdentifier: "bye", sender: nil)
}

Answer

user5886755 picture user5886755 · May 3, 2017

You can try this...

class SearchNew: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, GADInterstitialDelegate{

    var SearchBarValue:String!
    var searchActive : Bool = false
    var data : NSMutableArray!
    var filtered:NSMutableArray!

    @IBOutlet var searchBar: UISearchBar!
    @IBOutlet var tableView: UITableView!


    override func viewDidLoad() {

        super.viewDidLoad()


        self.searchBar.showsCancelButton = false
        tableView.tableFooterView = UIView(frame: CGRectZero)
        /* Setup delegates */
        tableView.delegate = self
        tableView.dataSource = self
        searchBar.delegate = self

        self.searchBar.delegate = self
        data = []
        filtered = []


        self.getData()

    }  //-----viewDidLoad closed------


    func getData()
    {

           //insert member data within data array
            data.addObject(member)
    }


    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        searchActive = true
    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        searchActive = false
    }

    func searchBarCancelButtonClicked(searchBar: UISearchBar) {
        searchActive = false;

        searchBar.text = nil
        searchBar.resignFirstResponder()
        tableView.resignFirstResponder()
        self.searchBar.showsCancelButton = false
        tableView.reloadData()
    }

    func searchBarSearchButtonClicked(searchBar: UISearchBar) {
        searchActive = false
    }

    func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
                return true
    }


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

            self.searchActive = true;
            self.searchBar.showsCancelButton = true


            filtered.removeAllObjects()

            dispatch_to_background_queue
                {
                    for  xdata in self.data
                    {
                        let nameRange: NSRange = xdata.rangeOfString(searchText, options: [NSStringCompareOptions.CaseInsensitiveSearch ,NSStringCompareOptions.AnchoredSearch ])

                        if nameRange.location != NSNotFound{

                            self.filtered.addObject(xdata)
                        }

                    }//end of for


                    self.dispatch_to_main_queue {
                        /* some code to be executed on the main queue */

                        self.tableView.reloadData()

            } //end of dispatch

        }


    }

    func dispatch_to_main_queue(block: dispatch_block_t?) {
        dispatch_async(dispatch_get_main_queue(), block!)
    }

    func dispatch_to_background_queue(block: dispatch_block_t?) {
        let q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
        dispatch_async(q, block!)
    }



    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

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

            return filtered.count

        }else{
            return data.count
            }
    }


    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "showDetailView") {
            if let destination=segue.destinationViewController as? DetailViewController{
                let path=tableView.indexPathForSelectedRow
                let cell=tableView.cellForRowAtIndexPath(path!)
                destination.passedValue=(cell?.textLabel?.text)            
            }
        }
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        searchBar.resignFirstResponder()
        searchBar.endEditing(true)
        self.view.endEditing(true)
        self.searchBar.showsCancelButton = false
        self.searchBar.text=""

    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell;

        if(searchActive){
            cell.textLabel?.text = filtered[indexPath.row] as! NSString as String
        } else {
            cell.textLabel?.text = data[indexPath.row]as! NSString as String

        }

        return cell;
    }
}

Hope it helps you.