Has anyone successfully retained a UISearchBar
in a tableHeaderView
of a UITableView
in ios11? Problems usually arise with iPhone X in landscape:
Apple recommends using the new searchController
property:
if (@available(iOS 11.0, *)) {
self.navigationItem.searchController = self.searchController;
self.navigationItem.hidesSearchBarWhenScrolling = NO;
} else {
self.tableView.tableHeaderView = self.searchController.searchBar;
}
However this doesn't always work. Here is an example with code:
iOS11 UISearchBar missing in UINavigationBar when embedded in UISplitViewController
So trying to keep the searchBar
in tableHeaderView
- a practical first step is to apply the appropriate auto layout constraints:
if (@available(iOS 11.0, *)) {
UILayoutGuide *guide = self.tableView.safeAreaLayoutGuide;
searchBar.translatesAutoresizingMaskIntoConstraints = NO;
[searchBar.leftAnchor constraintEqualToAnchor:guide.leftAnchor].active = YES;
[searchBar.rightAnchor constraintEqualToAnchor:guide.rightAnchor].active = YES;
}
The searchBar
is then correctly sized when displayed:
However the problem arises when the UISearchBar
is activated:
This seems to be an old problem. There are numerous stackoverflow questions and answers relating to issues like this. In this case, on inspection of the view hierarchy, it appears the width of the UISearchBar
is set incorrectly. So this can be corrected:
- (void)didPresentSearchController:(UISearchController *)searchController NS_AVAILABLE_IOS(11_0)
{
if (@available(iOS 11.0, *)) {
CGRect frame = self.searchController.searchBar.frame;
frame.size.width = [self safeWidthAvailable];
self.searchController.searchBar.frame = frame;
}
}
- (CGFloat)safeWidthAvailable
{
CGRect frame = ((AppDelegate *)MyApplication.sharedApplication.delegate).window.frame;
CGFloat width = frame.size.width;
if (@available(iOS 11.0, *)) {
UIEdgeInsets insets = ((AppDelegate *)MyApplication.sharedApplication.delegate).window.safeAreaInsets;
width -= insets.left;
width -= insets.right;
}
return width;
}
So this works:
Until you rotate with UISearchController
active:
So again UISearchController
has misplaced UISearchBar
.
Why is this so hard?
One solution is to save the search, disable UISearchController
after a rotation, and re-enable it with the saved search. This works, but it shouldn't need to be so complicated.
Any suggestions?