I'm having a problem that many other users have asked about on StackOverflow (examples: 1 , 2 , 3 ).
I'd like to have a fixed search bar when scrolling a tableview. I originally had a UITableViewController
with a UISearchBar
on top.
Most solutions recommended that I should have a UIViewController
with a UISearchBar
and a UITableView
below it. I did exactly this. Below is a screenshot of my interface builder.
This solution doesn't fix it, however :( The search bar still doesn't float, and when scrolling it will hide behind the navigation bar.
I have also tried this solution but I'd rather not have the search bar in the navigation bar itself.
Here's all of my TableView or Search related code (I removed everything irrelevant):
class NumberSelectorViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchControllerDelegate {
@IBOutlet var searchBar: UISearchBar!
@IBOutlet var tableView: UITableView!
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchController.searchResultsUpdater = self as UISearchResultsUpdating
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
// NOTE: Removing thie line removes the search bar entirely.
tableView.tableHeaderView = searchController.searchBar
addCancelButton()
}
// MARK: - Table view data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching() == true {
return filteredNumberList.count
}
return NumberList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "numberCell")! as UITableViewCell
if isSearching() == true {
cell.textLabel?.text = filteredNumberList[indexPath.row].NumberName
} else {
cell.textLabel?.text = NumberList[indexPath.row].NumberName
}
return cell
}
// MARK: - Table view delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if isSearching() == true {
selectedNumber = filteredNumberList[indexPath.row]
} else {
selectedNumber = NumberList[indexPath.row]
}
performSegue(withIdentifier: "someSegue", sender: self)
}
// MARK: Searching
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredNumberList = NumberList.filter({ (Number) -> Bool in
return (Number.NumberName?.lowercased().contains(searchText.lowercased()))!
})
tableView.reloadData()
}
// MARK: Search Bar
func isSearching() -> Bool {
return (searchController.isActive && searchController.searchBar.text != "")
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredNumbersList.removeAll()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.tableView.reloadData()
}
extension NumberSelectorViewController: UISearchResultsUpdating {
public func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchText: searchController.searchBar.text!)
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterContentForSearchText(searchText: searchController.searchBar.text!)
}
}
}
I actually discovered the answer. The issue was simply that I had the line:
tableView.tableHeaderView = searchController.searchBar
I removed this, and then the search bar disappeared, but it was only being hidden behind the navigation bar! So I played around with the constraints on the interface builder and it now works as normal :)
It appears you added the search bar to your view properly, it's just hidden under navigation bar. Try in viewDidLoad
self.edgesForExtendedLayout = UIRectEdgeNone;
and get rid of
tableView.tableHeaderView = searchController.searchBar
you don't need to add the searchBar in the tableView or its header.
In your viewDidLoad method you can give the Edge Inset so that the content in tableView is not overlapped by the searchBar
override func viewDidLoad() {
super.viewDidLoad()
let edgeInsets = UIEdgeInsetsMake(52, 0, 0, 0)
self.tableView.contentInset = edgeInsets
self.tableView.register(UINib(nibName: "AbcCell", bundle: nil), forCellReuseIdentifier: "AbcCell")
}
Following is an image how i have placed it in one of my project and it dosen't float.
我是另一种观点,所以你可以把它放在任何地方
anyView.addSubview(searchController.searchBar)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.