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
Swift Running Code in Periodically Background
How to Read a File from The Filesystem in a Swift Command Line App
Swiftui - Form with Error Message on Button Press and Navigation
How to Observe Torchlevel in Swift
Use Tableviewcontroller Inside Skscene
Nstimer() - Timer.Invalidate Not Working on a Simple Stopwatch
Add Value to Variable Inside Closure in Swift
Error Is Value of Type 'Authdataresult' Has No Member 'Uid'
Collision Detection Leading to Color Detection
Social Framework Is Deprecated in iOS11
How to Pull The Artist Value from Mpmediaitemcollection
Firebase Cloud Firestore - Initializing a Collection
How to Remove Items from an Array When Deselecting a Row in a UItableview