Hide search bar when cancel button is pressed, and resize navbar

Viewed 1434

I have a search bar implemented using a UISearchController inside my navigation bar. There is also a table view whose top constraint is set to the bottom of the navigation bar.

Desired behaviour: When the cancel button is pressed, the search bar is hidden and the top constraint of the table view returns to what it was before the search bar was removed (see screenshot #1 at the end of this post)

Current behaviour: When the cancel button is pressed, the search bar is gone but the top constraint of the tableView does not change in response (see screenshot #3)

A possible solution to this problem would be to manually update constraints whenever the cancel button is clicked. However, I can't find a way to access the tableView's constraints from the UISearchBarDelegate method searchBarCancelButtonClicked

Code Snippet:

class ViewController: UIViewController {

    let searchController = UISearchController(searchResultsController: nil)

    override func viewDidLoad() {
        super.viewDidLoad()

        searchController.searchBar.delegate = self

        /* Adding search button to the navbar */

        /* setting tableView constraints */

        /* tableView delegate/datasource methods, etc... */
    } 

    @objc func searchButtonTapped(_ sender: UIBarButtonItem) {
        setup()
        navigationItem.searchController = searchController
    }

    func setup() {
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.sizeToFit()
    }
}

extension UISearchBarDelegate {
    public func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {

        navigationItem.searchController = nil

        /* Cannot access tableview constraints from here because extension is outside of the class */
    }
}

Before the search button is pressed.

Before the cancel button is pressed. enter image description here

After the cancel button is pressed. enter image description here

3 Answers

Add one line code as following:

func searchBarCancelButtonClicked(_ searchBar: UISearchBar){

   self.navigationItem.searchController = nil

   self.view.setNeedsLayout()

 /* Cannot access tableview constraints from here because extension is outside of the class */
}

(YES this is right thing)

func searchBarCancelButtonClicked(_ searchBar: UISearchBar){

   self.navigationItem.searchController = nil

   self.view.setNeedsLayout()

 /* Cannot access tableview constraints from here because extension is outside of the class */
}

Try to update the view inside the navigation controller like this:

func searchBarCancelButtonClicked(_ searchBar: UISearchBar){
    navigationItem.searchController = nil // or searchController
    navigationController?.view.setNeedsLayout() // invalidate current layout 
    navigationController?.view.layoutIfNeeded() // force update layout
}
Related