Search code examples
swifttableviewsegueuisearchcontrollerdidselectrowatindexpath

App crashing when selecting table row while search controller Active


My app seems to crash whenever I select a table row while my search controller is active.

Things to note:

  • My search controller is embedded into my table header
  • I currently have a fix, however, it requires my search controller to be dismissed when table row selected. This makes for poor UI experience. I don't want to have to dismiss my search controller

Here is some of my code:

class ViewProfileViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UISearchBarDelegate, UISearchResultsUpdating {

let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
    super.viewDidLoad()

    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.sizeToFit()
    searchController.searchBar.searchBarStyle = .minimal
    searchController.searchBar.placeholder = "Search City"
    searchController.searchBar.showsCancelButton = true
    searchController.searchBar.delegate = self
    searchController.searchBar.backgroundColor = UIColor.white

    self.myTable.tableHeaderView = searchController.searchBar

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    if searchController.isActive {
        navigationController?.popViewController(animated: true)
        dismiss(animated: true, completion: nil)
    } else {

    }
    let mViewController = MController()
    let navController = UINavigationController(rootViewController: mViewController)
    present(navController,animated: true, completion: nil)
}

}

Solution

  • Don't pop the view controller on cell selection. No need to check if the searchController is active either.

    Example:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // Get rid of searchController
        searchController.searchBar.endEditing(true)
        searchController.isActive = false
        searchController.dismiss(animated: true) { /* */ }
    
        // Deselect row
        tableView.deselectRow(at: indexPath, animated: true)
    
        // Present your VC here
    
    }