2

We're having a weird issue with using a UISearchController as an item in a navigation bar. It's set as the left bar button item and when a user taps to start searching, the search bar expands to the right off the side of the screen.

Below is the code for creating the UISearchController:

resultSearchController = ({
    let controller = UISearchController(searchResultsController: nil)
    controller.searchResultsUpdater = self
    controller.dimsBackgroundDuringPresentation = false
    controller.hidesNavigationBarDuringPresentation = false
    controller.searchBar.delegate = self
    controller.delegate = self

    controller.searchBar.frame = CGRect(x: 0, y: 0, width: 266, height: 44.0)
    let searchBarView = UIView(frame: controller.searchBar.frame)
    searchBarView.addSubview(controller.searchBar)

    controller.searchBar.backgroundImage = UIImage(named: "searchBarBG")
    controller.searchBar.barTintColor = .white
    controller.searchBar.subviews[0].subviews.flatMap(){ $0 as? UITextField }.first?.tintColor = Constants.Colors.Red

    navigationItem.leftBarButtonItem = UIBarButtonItem(customView: searchBarView)

    return controller
})()

When the screen first loads, it looks like this.

After tapping on the search bar, it changes to look like this.

I have no idea what's causing this. After lots of searching, I tried changing self.definesPresentationContext = false; and self.extendedLayoutIncludesOpaqueBars = true as well as adjusting similar checkboxes in the storyboard. Any tips?

Edit: This only seems to happen on iOS 11. In 10.3, the search bar actually shrinks a little to accommodate the Cancel button but ultimately takes up the same amount of space.

Nick M
  • 51
  • 1
  • 6
  • Does it change if you alter the constants in controller.searchBar.frame? – Carlos Nov 02 '17 at 18:17
  • It changes the starting size of the search bar, but it still expands out past the side of the screen when tapped. – Nick M Nov 02 '17 at 18:23
  • Have you checked the constraints on it? Beware of error messages related to the constraints breaking. – Carlos Nov 02 '17 at 18:25
  • We don't have any constraints on it. It's created programmatically as shown above. – Nick M Nov 02 '17 at 19:29

2 Answers2

2

I ended up fixing this by overriding the didPresentSearchController and didDismissSearchController methods as part of the UISearchControllerDelegate.

extension ContactUsViewController: UISearchControllerDelegate {

    func didPresentSearchController(_ searchController: UISearchController) 
    {
        searchController.searchBar.frame = CGRect(x: 0, y: 0, width: 266, height: 44.0)
    }

    func didDismissSearchController(_ searchController: UISearchController) 
    {
        searchController.searchBar.frame = CGRect(x: 0, y: 0, width: 266, height: 44.0)
    }
}
Nick M
  • 51
  • 1
  • 6
  • This along with https://stackoverflow.com/a/31106630/2704776 helped me to solve - note I had my search controller in a view not the nav bar – devjme Sep 09 '19 at 18:55
1

If you don't need the added functionality of UISearchBarController you can directly use UISearchBar, which has a more predictable resizing behavor:

let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: 200, height: 20))
searchBar.delegate = self
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: searchBar)

Note that if you use the built-in cancel button or other similar features you'll have to manually handle them in the delegate methods.

dr_barto
  • 5,723
  • 3
  • 26
  • 47