danutha
danutha

Reputation: 214

How to implement a custom search-bar when the array type is JSON

I'm working on a project in swift 3 and I have a specific UIViewController where I have a UITableView and as to populate data on its cell, the data is get from the server and I assign it to an array of the type JSON. Thus, I have a UISearch bar placed at a different place in the same UIViewController(not as the header of the UITableView). My requirement is to implement the functionality of the search bar where i could filter and search the data of my UITableView. How can I achieve this? I worked on the code half way though which is not fucntioning and the code as bellow.

import UIKit
import SwiftyJSON
import SDWebImage


class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdating,UISearchBarDelegate {
    @IBOutlet weak var tableView: UITableView!
    var count : Int = 0
    var searchActive : Bool?
    var selectedCategoryList = [JSON?]()
    var filterSelectedCategoryList = [JSON?]()
    let searchController = UISearchController(searchResultsController: nil)
    override func viewDidLoad() {
        super.viewDidLoad()
        passJson()

        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        searchController.searchBar.sizeToFit()
        self.tableView.tableHeaderView = searchController.searchBar
        searchController.searchBar.delegate = self
        self.tableView.reloadData()

        // Do any additional setup after loading the view, typically from a nib.
    }




    func updateSearchResults(for searchController: UISearchController) {




    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        filterSelectedCategoryList = selectedCategoryList.filter { titles in
            return (titles?["title"].stringValue.lowercased().contains(searchText.lowercased()))!
        }
        tableView.reloadData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func passJson() {
        let path : String = Bundle.main.path(forResource: "JsonFile", ofType: "json") as String!

        let jsonData = NSData(contentsOfFile: path) as NSData!

        let readableJson = JSON(data: jsonData as! Data, options: JSONSerialization.ReadingOptions.mutableContainers, error: nil)

        let json = readableJson

         print(json)

        let selectedItemArray = json["itemList"].arrayValue
        self.selectedCategoryList = selectedItemArray
        print("new prints",self.selectedCategoryList)
        // print( "Count",selectedItemArray?.count as Any)


        self.count = self.selectedCategoryList.count
        print(self.count)


    }


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


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.searchController.isActive && searchController.searchBar.text != ""{
            return filterSelectedCategoryList.count
        }else{
            return selectedCategoryList.count
        }

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
        if count > 0 {
            if self.searchController.isActive && searchController.searchBar.text != ""{

                cell.label.text = filterSelectedCategoryList[indexPath.row]?["healerName"].stringValue

            }else{
                cell.label.text = selectedCategoryList[indexPath.row]?["healerName"].stringValue
            }


        }
        return cell
    }



}

Upvotes: 0

Views: 795

Answers (1)

Nirav D
Nirav D

Reputation: 72410

Try to implement the UISearch​Bar​Delegate method but before that set the searchBar.delegate to self in your viewDidLoad.

override func viewDidLoad() {
    super.viewDidLoad()
    passJson()

    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = false
    definesPresentationContext = true
    searchController.searchBar.sizeToFit()

    //Set the delegate of searchBar
    searchController.searchBar.delegate = self

    self.tableView.reloadData()
}

Now implement the search​Bar(_:​text​Did​Change:​) method of UISearchBarDelegate and filter your array in that method.

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    filterSelectedCategoryList = selectedCategoryList.filter { titles in
        return (titles?["healerName"].stringValue.lowercased().contains(searchText.lowercased()))!
    }
    tableView.reloadData()
}

Upvotes: 1

Related Questions