General remarks:
- iOS 13.5
- The desired behavior is for the bar to (1) remain visible, (2) it's original position, (3) even when selected and the keyboard appears.
- The problem only occurs when the UISearchBar obtained using a UISearchController. The problem does not appear when a UISearchBar is instantiated directly.
- The parent view controller is of type
UIViewController
. There is noUINavigationController
in the hierarchy. - the bar is laid out programmatically using the fluent constraint API as shown below. Note: one potential point of concern is that the height is not explicitly set.
- this answer seems to indicate that
UISearchController
possesses subtle behaviors which do not play well with auto layout. this answer prescribes using a placeholder view to wrap thesearchBar
. still, it is unclear precisely what is the appropriate remediation: https://stackoverflow.com/a/35231501/13538737
The code is implemented exactly as shown here:
class RootViewController: UIViewController {
let search: UISearchController = {
let x = UISearchController(searchResultsController: nil)
x.searchBar.placeholder = "Search Ingredients"
x.searchBar.autocapitalizationType = .none
x.searchBar.autocorrectionType = .no
x.searchBar.translatesAutoresizingMaskIntoConstraints = false
return x
}()
var bar: UIView {
return search.searchBar
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .brown
view.addSubview(bar)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let guide = view.safeAreaLayoutGuide
bar.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
bar.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
bar.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
}
}
The RootViewController is added to the top-level hierarchy as follows:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = RootViewController()
self.window = window
window.makeKeyAndVisible()
}
}
}
Here is a GIF demonstrating the visual defect: