I am using UISearchController
to search for data in my tableview. I am not using table view controller. I would like to hide the navigation bar when my search b
Not the best solution but just to workaround.
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return searchController.isActive ? 20.0f : 0.0f;
}
This is how I set up the search bar and things in viewDidLoad (copied from some of apple's examples).
It presents the found results in the same view controller as your unfiltered data is shown. It also has its search bar in the table header that is hidden until it is needed.
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
[self.searchController.searchBar sizeToFit];
// we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO; // default is YES
self.searchController.searchBar.delegate = self; // so we can monitor text changes + others
// Search is now just presenting a view controller. As such, the normal view controller
// presentation semantics apply. Namely, that presentation will walk up the view controller
// hierarchy until it finds the root view controller or one that defines a presentation context.
//
self.definesPresentationContext = YES; // know where you want UISearchController to be displayed
// Hides search bar initially. When the user pulls down on the list, the search bar is revealed.
[self.tableView setContentOffset:CGPointMake(0, self.searchController.searchBar.frame.size.height)];
I have seen similar behavior. Most probably, your table view controller is not implementing heightForHeaderInSection. Precise height of cell is not known, this leads to number of issues like yours.
I have the same trouble. And research didn't answer. My decision:
1) I used UITableviewController with SearchController and when I taped on the field I had this UI trouble: Extra blank space between searchBar and tableview The guys noted that you need to use the searchController with UIViewcontroller and tableView separately. So I did
2) There was this problem. It is solved as follows:
let searchController = UISearchController(searchResultsController: nil)
var tableView:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
loadData()
setupTableView()
setupSearchController()
}
private func setupTableView(){
tableView = UITableView(frame: CGRect.zero, style: .plain)
**//next 2 very important line of code**
tableView.autoresizingMask = UIViewAutoresizing()
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
tableView.dataSource = self
tableView.delegate = self
tableView.register(LetterBrandCell.self, forCellReuseIdentifier: "brandCell")
tableView.tableFooterView = UIView()
addConstraints()
}
In the method of adding constraints, it is important to be attached to top & bottomLayoutGuides, not just to view:
private func addConstraints(){
NSLayoutConstraint(item: tableView,
attribute: .top,
relatedBy: .equal,
toItem: topLayoutGuide,
attribute: .bottom,
multiplier: 1,
constant: 0).isActive = true
NSLayoutConstraint(item: tableView,
attribute: .bottom,
relatedBy: .equal,
toItem: bottomLayoutGuide,
attribute: .top,
multiplier: 1,
constant: 0).isActive = true
NSLayoutConstraint(item: view,
attribute: .leading,
relatedBy: .equal,
toItem: tableView,
attribute: .leading,
multiplier: 1,
constant: 0).isActive = true
NSLayoutConstraint(item: view,
attribute: .trailing,
relatedBy: .equal,
toItem: tableView,
attribute: .trailing,
multiplier: 1,
constant: 0).isActive = true
}
Reseting tableView.tableHeaderView = searchController.searchBar
after the dismissing searchController solved the issue for me.
public func didDismissSearchController(_ searchController: UISearchController) {
tableView.tableHeaderView = searchController.searchBar
}
Unfortunately didDismissSearchController
doesn't get called if you select a result and go back to parent viewController.
In this case you need reset the searchBar.frame back to origin position:
if let frame = tableView.tableHeaderView?.frame {
searchController.searchBar.frame = frame
}
I managed to resolve this issue by combining RJiryes answer with scroll to top.
-(void)willPresentSearchController:(UISearchController *)searchController{
[self.contactsTableView setContentInset:UIEdgeInsetsMake(20, 0, 0, 0)];
[self.contactsTableView setContentOffset:CGPointMake(0.0f, -self.contactsTableView.contentInset.top) animated:YES];
}
-(void)willDismissSearchController:(UISearchController *)searchController{
[self.contactsTableView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
}