Uisearchcontroller Hiding Status Bar on iOS 11 Swift 4

Search bar overlaps with status bar on iOS 11

I found that the problem was that the presenting view Controller also sets

override open func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = [];
self.automaticallyAdjustsScrollViewInsets = false;
}

I have to do this because the table view does not actually extend all the way to the top.

I solved this like that in my presenting view Controller:

override open func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false;
if (@available(iOS 11.0, *)) {
//NSLog(@"iOS 11.0");
} else {
self.edgesForExtendedLayout = UIRectEdgeNone;
//NSLog(@"iOS < 11.0");
}
}

Seems to be an iOS 11 bug, or at least an odd behavior…

Show search bar in navigation bar without scrolling on iOS 11

The following makes the search bar visible at first, then allows it to hide when scrolling:

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if #available(iOS 11.0, *) {
navigationItem.hidesSearchBarWhenScrolling = false
}
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if #available(iOS 11.0, *) {
navigationItem.hidesSearchBarWhenScrolling = true
}
}

Using isActive didn't do what I wanted, it makes the search bar active (showing cancel button, etc.), when all I want is for it to be visible.

UISearchController.hidesNavigationBarDuringPresentation ignored with scopeButtons in iOS 11 Beta

OK, found the cause of the problem while I was researching another related issue, that the searchBar and the scope button got mis-aligned in iOS 11. The key is that the searchController configuration scheme has changed in iOS 11 where searchBar should no longer be presented as the tableView's headerView, instead, the whole searchController should be part of the navigationItem, as illustrated below:

if #available(iOS 11.0, *) {
self.navigationItem.searchController = searchController
// optional, but apparently due to a bug in iOS 11,
// the searchBar and the scope buttons may get too high and mis-aligned
// when the nav bar is hidden
searchController?.hidesNavigationBarDuringPresentation = false
} else {
tableView.tableHeaderView = searchController!.searchBar
}

The above code fixed a few UI problems I had related to UISearchBar in iOS 11, and is actually recommended in this WWDC 2017 video, but how I wish if Xcode could give us a warning at the old tableHeaderView assignment line, it would have saved me and probably quite some other developers' confusion and research time.

UISearchController Not Redisplaying Navigation Bar on Rotate

It looks like the UISearchController forgets to reset the frame of the searchBar when the status bar reappears. I think this is probably a bug in UISearchController; there seem to be a few listed in radar. It seems the searchBar's superview (which is internal to the UISearchController) ends up with the wrong height. This is vexing since the solution therefore involves reaching into the searchController's view hierarchy, which Apple could change... you might want to add a check of the iOS version so it only runs for specified versions.

If you add the code below to your view controller, it will be called when the trait collection changes. It checks to see a) the search controller is active, b) the statusBar is not hidden, and c) the searchBar origin-y is 0, and if so it increases the height of the superview by the height of the statusBar, which moves the searchBar down.

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
let app = UIApplication.sharedApplication()
if searchController!.active && !app.statusBarHidden && searchController?.searchBar.frame.origin.y == 0 {
if let container = self.searchController?.searchBar.superview {
container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + app.statusBarFrame.height)
}
}
}

Objective C

- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {

[super traitCollectionDidChange: previousTraitCollection];

if(self.venueSearchController.active && ![UIApplication sharedApplication].statusBarHidden && self.venueSearchController.searchBar.frame.origin.y == 0)
{
UIView *container = self.venueSearchController.searchBar.superview;

container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height);
}
}


Related Topics



Leave a reply



Submit