1
votes

I have a very simple ViewController (embedded in the NavigationController). From the NavigationBar you can open a UISearchController to look for some information. The search result is in a very simple TableViewController.

When the UISearchController is displayed there're some extra space between the SearchController and the TableViewController. It's seems it's 20px like the height of the status bar.

How can I remove this extra space?

See screenshots.

enter image description here enter image description here

Here the code of the ViewController

class ViewController: UIViewController {

    var theSearchController:UISearchController?


    @IBAction func openSearchController(_ sender: UIBarButtonItem) {
        showSearchController()
    }

    /// Display the search controller used to look for a POI, address, ...
    func showSearchController() {
        let mySearchController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SearchControllerId") as! SearchTableViewController

        theSearchController = UISearchController(searchResultsController: mySearchController)

        // Configure the UISearchController
        theSearchController!.searchResultsUpdater = self
        theSearchController!.delegate = self

        theSearchController!.searchBar.sizeToFit()
        theSearchController!.searchBar.delegate = self
        theSearchController!.searchBar.placeholder = NSLocalizedString("MapSearchPlaceHolder", comment: "")
        theSearchController!.hidesNavigationBarDuringPresentation = true
        theSearchController!.dimsBackgroundDuringPresentation = true

        present(theSearchController!, animated: true, completion: nil)

    }

}

extension ViewController: UISearchResultsUpdating, UISearchBarDelegate, UISearchControllerDelegate {
    func updateSearchResults(for searchController: UISearchController) {
        let mySearchController = searchController.searchResultsController as! SearchTableViewController
        mySearchController.reloadAll()
    }
}

Here the code of the TableViewController

class SearchTableViewController: UITableViewController {

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Mandatory to make sure the TableView is displayed when the search field is empty
        // when user touch it.
        view.isHidden = false
    }


    func reloadAll() {
        view.isHidden = false
        tableView.reloadData()
    }
    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 2
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Section \(section)"
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "testCellId", for: indexPath)

        cell.textLabel?.text = "text \(indexPath.section) / \(indexPath.row)"

        return cell
    }
}

Edit:

The answer from Rizvan Rzayev solve the issue of the space between the UISearchController and the UITableviewController. Next, there's still an issue because the bottom of the tableview are hidden by the keyboard and then some rows cannot be displayed.

To solve this keyboard issue and the initial issue here the full code:

import UIKit

class SearchTableViewController: UITableViewController {

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Mandatory to make sure the TableView is displayed when the search field is empty
        // when user touch it.
        view.isHidden = false
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

    }

    deinit {
        unregisterKeyboardNotifications()
    }

    func reloadAll() {
        view.isHidden = false
        tableView.reloadData()
    }
    // MARK: - Table view data source

    func unregisterKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    }

    func registerKeyboardNotifications() {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(SearchTableViewController.keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillShow,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(SearchTableViewController.keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)
    }

    var keyboardHeight:CGFloat = 0.0

    @objc func keyboardWillShow(_ notification:Notification) {
        // Extract the Keyboard size

        let info = notification.userInfo! as NSDictionary
        let valueHeight = info.value(forKey: UIKeyboardFrameEndUserInfoKey) as! NSValue
        let keyboardForHeight = valueHeight.cgRectValue.size
        keyboardHeight = keyboardForHeight.height
        let contentInsets = UIEdgeInsetsMake(40, 0.0, keyboardForHeight.height, 0.0)
        tableView.contentInset = contentInsets
        tableView.scrollIndicatorInsets = contentInsets
    }


    @objc func keyboardWillHide(_ notification:Notification) {
        tableView.contentInset = .zero
        tableView.scrollIndicatorInsets = .zero
    }


    override func numberOfSections(in tableView: UITableView) -> Int {

        return 2
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Section \(section)"
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "testCellId", for: indexPath)

        cell.textLabel?.text = "text \(indexPath.section) / \(indexPath.row)"

        return cell
    }

    override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        tableView.contentInset = UIEdgeInsets(top: 40, left: 0, bottom: keyboardHeight, right: 0)
        tableView.scrollIndicatorInsets = tableView.contentInset
    }
}
1

1 Answers

1
votes

Try it!

    override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    tableView.contentInset = UIEdgeInsets(top: 65, left: 0, bottom: 0, right: 0)

}