0

Is it possible to create UISearchController for reusable use in many classes?

To use a minimum of code in new classes.

Now I have code in all classes, but I want to use minimum code in all classes to call searchController:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {

    @IBOutlet weak var tableView: UITableView!

    var photoBook: [PhotoBooking] = []
    var filteredBook: [PhotoBooking] = []

    private var searchController = UISearchController(searchResultsController: nil)
    private var searchBarIsEmpty: Bool {
        guard let text = searchController.searchBar.text else { return false }
        return text.isEmpty
    }

    private var isFiltering: Bool {
        return searchController.isActive && !searchBarIsEmpty
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        configureSearchController()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isFiltering {
            return filteredBook.count
        }
        return photoBook.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        var pBook: PhotoBooking
        if isFiltering {
            pBook = filteredBook[indexPath.row]
        } else {
            pBook = photoBook[indexPath.row]
        }
        cell.textLabel?.text = pBook.invoiceID
        cell.detailTextLabel?.text = pBook.contactInfo["surname"] as! String
        return cell
    }

    private func configureSearchController() {
        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.searchBar.barTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.delegate = self
        tableView.tableHeaderView = searchController.searchBar
        definesPresentationContext = true
    }
}

extension AllPhotoBookingsViewController: UISearchResultsUpdating {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        filterContentForSearchText(searchBar.text!)
        tableView.reloadData()
    }

    func updateSearchResults(for searchController: UISearchController) {
        filterContentForSearchText(searchController.searchBar.text!)
        tableView.reloadData()
    }

    private func filterContentForSearchText(_ searchText: String) {
        filteredBook = photoBook.filter({ (book: PhotoBooking) -> Bool in
            let name = book.contactInfo["name"] as! String
            let surname = book.contactInfo["surname"] as! String
            let invoice = book.invoiceID
            return invoice.localizedCaseInsensitiveContains(searchText) ||
                name.localizedCaseInsensitiveContains(searchText) ||
                surname.localizedCaseInsensitiveContains(searchText)
        })
        tableView.reloadData()
    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        navigationController?.hidesBarsOnSwipe = false
    }
}

Maybe need use protocol, but I don't understand how to use correctly protocol.

  • I guess [this](https://stackoverflow.com/a/36219022/5928311) should help you (customize your `UISearchController` and prepare for reuse) – Vadim Nikolaev Jan 08 '20 at 14:44

1 Answers1

0

There are many ways of doing this, using protocols is a great approach, but you could also subclass UIViewController and make a BaseSearchableViewController where you would add all the functionality you need for your search, then, you just subclass from BaseSearchableViewController instead of UIViewController.

javier rivarola
  • 500
  • 3
  • 6