Tyler Wasick
Tyler Wasick

Reputation: 89

Search results disappear when tapping on search results

I am working on a UITableView with a search bar on the top of it (search bar is setup programmatically). I am able to view the search results, but when I tap outside of the search bar I the results are cleared. I'm sure it's something simple to implement, but I can't figure it out. Any help or feedback is appreciated!

//
//  InventoryViewController.swift
//  ItemizePro
//
//  Created by Tyler Wasick on 5/18/20.
//  Copyright © 2020 Tyler Wasick. All rights reserved.
//

import UIKit

class InventoryViewController: UIViewController {
    
    @IBOutlet weak var inventoryTableView: UITableView!
    
    var assetList = [Asset]()
    let searchController = UISearchController(searchResultsController: nil)
    var filterAssetList = [Asset]()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        // Configure the tableview delegate and data source
        inventoryTableView.delegate = self
        inventoryTableView.dataSource = self
        
        // Download asset list
        FirebaseDB.downloadAssetList { (list) in
            self.assetList = list
            self.inventoryTableView.reloadData()
        }
        
        // Setup Search Delegate
        searchController.searchResultsUpdater = self
        definesPresentationContext = true
        inventoryTableView.tableHeaderView = searchController.searchBar
        
    }
    
    // MARK: - Functions
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(indexPath)
    }
    
    
    
    // Search bar function, looks to match name from the search to asset name
    private func filterAssets(for searchText:String) {
        filterAssetList = assetList.filter({ (asset) -> Bool in
            return (asset.name?.lowercased().contains(searchText.lowercased()))!
        })
        inventoryTableView.reloadData()
    }
    
    

}

extension InventoryViewController: UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {
    
    func updateSearchResults(for searchController: UISearchController) {
        filterAssets(for: searchController.searchBar.text ?? "")
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        // If there is no search use the "assetList" array, if not use "filterAssetList" array
        if filterAssetList.count == 0 {
            return assetList.count
        } else {
            return filterAssetList.count
        }
         
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        // Format date field
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .none
                
        // Set the cell with asset data
        let cell = tableView.dequeueReusableCell(withIdentifier: Constants.Storyboards.TableViewCell.inventoryCellID) as! InventoryListView
        
        // Get the asset for that rown
        // Initiate emtpy variable
        var cellAsset = Asset()
        if filterAssetList.count == 0 {
            cellAsset = assetList[indexPath.row]
        } else {
            cellAsset = filterAssetList[indexPath.row]
        }
        
        // Set the cell details
        cell.setInventoryCell(cellAsset)

        // Return the row
        return cell
    }
}

Upvotes: 1

Views: 242

Answers (1)

NinjaDeveloper
NinjaDeveloper

Reputation: 1712

I found it is easier to create a variable flag var isSearching = false and use it instead of filterAssetList count. this flag keeps track of the "Search Bar" I use this tutorial as reference and it helps me a lot :)
https://daddycoding.com/2018/12/07/ios-tutorials-search-your-table-using-a-searchbar/

https://github.com/zhiyao92/Search-Bar

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var searchBar: UISearchBar!
    
    var data = ["Apple","Microsoft","Twitter","Facebook","Instagram"]
    var filteredData = [String]()
    var isSearching = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.delegate = self
        tableView.dataSource = self
        searchBar.enablesReturnKeyAutomatically = false
        tableView.keyboardDismissMode = .onDrag
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isSearching {
            return filteredData.count
        } else {
            return data.count
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        if isSearching {
            cell.textLabel?.text = filteredData[indexPath.row]
        } else {
            cell.textLabel?.text = data[indexPath.row]
        }
        return cell
    }
}

extension ViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text == "" {
            isSearching = false
            tableView.reloadData()
        } else {
            isSearching = true
            filteredData = data.filter({$0.contains(searchBar.text ?? "")})
            tableView.reloadData()
        }
    }
}

Upvotes: 1

Related Questions