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.
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
}
}