Reputation: 89
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
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